n&(n-1)能记录二进制中1的个数的原理详解

文章解释了一个计算整数n二进制中1的个数的C语言函数,通过递归和位操作(A-1)的原理,每次将第一位的1变为0,直到n减为0。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

无意发现个代码,看大多博主都没说明原理,在这里解释一下:

找出n的二进制位为1的个数

 int number_of_1(int n)
{
	int count = 0;
	while (n)
	{
		m = n & (n - 1);
		count++;
	}
	return count;
}

原理:
(A、B为二进制,且B = A - 1)
A:10010011010100
B:10010011010011 = A-1

  1. 先看A、B的公共部分:(红色标注)

    • A:1001001101010000
    • B:1001001101001111
    • A公共部分 & B公共部分 = A&B公共部分 -> 数字不变
  2. 现在我们主要分析的是,非公共部分:

    • A:10010011010 10000
    • B:10010011010 01111

现在假设:

  • k : A中第个二进制为 1 的位置
  • 则 k 前面的二进制数必然全是0
  • 那么B = A-1之后,从1~k-1的位置肯定都要借位,恰好到k的位置1 -> 0
高位 <- 低位第k位:(第一个是1的位置)1~k-1位
A1001001101010000
B1001001101001111
A&B1001001101000000

然后A = A&B = 10010011010 00000

  • 可以看到,经过A&B之后,发生的唯一变化是,第一个出现的1 变成了 0
  • 或者通俗点讲:n&(n-1) 实现的效果就是把 第一个为 1 的二进制位转化为0 ,其他部分不变

然后处理
A = 100100110 1000000
B = 100100110 0111111
可以看出:蓝色部分为刚刚二进制位为1的数,

划分公共部分:
A= 1001001101000000
B= 1001001100111111

然后相同操作:

高位 <- 低位第k位:(第一个是1的位置)1~k-1位
A100100110101000000
B100100110100111111
A&B100100110100000000

然后,不断递归就行了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值