二进制中1的个数(python)

一:问题描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

二:问题分析
首先复习一下源码,补码和反码的区别:
原码
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

[+1]原 = 0000 0001

[-1]原 = 1000 0001

第一位是符号位.

反码

正数的反码是其本身

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

[+1] = [00000001]原 = [00000001]反

[-1] = [10000001]原 = [11111110]反

补码

正数的补码就是其本身

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补

接下来就可以举个栗子了
题目告诉我们,输入正数是原码,输入负数是补码
2=0000 0000… 0000 0010
-2(反)=1111 1111… 1111 1101
-2(补)=1111 1111…1111 1110

第一种方法,我们让n和1111 …1111(32位)做按位与运算
然后去数里面1的数量
二进制中1的个数(python)
这里的0xFFFFFFFF表示32位的1,也表示我们最后只取到32位,起一个限位的作用

第二种方法:

二进制中1的个数(python)
这里的1<<i表示把数字1左移i位
注意不可以写成if mask & n ==1:
二进制中1的个数(python)
第三种方法:
二进制中1的个数(python)
这种方法怎么理解呢?
我们输入一个n

n:0000 0101
n-1:0000 0100

他两做与运算:
0000 0100
再减去1:
0000 0011

再做与运算:
0000 0000

至此我们做了2次与运算,所以输出为2,即n中有2个1