python查看负数的补码以及对二进制的操作

在python中查看十进制的方法是使用bin(),在python中是没有位数这一概念的,所以显示是这样的:

>>bin(5)
'0b101'
>>bin(-5)
'-0b101

发现对于负数的表示是负号加源码,这样很不方便,我们可以通过以下方式查看负数的补码:

>>bin(-5 & 0xffffffff)
'0b11111111111111111111111111111011'

但是注意,python是没有位数这一概念的,它识别二进制是否是正负依赖正负号来判别。这里的'0b111111111111111111111111111111111011'只是形式和-5的32位二进制编码相同,但是python会将'0b111111111111111111111111111111111011'视为正数('0b111111111111111111111111111111111011'的首位不是1,这是因为python没有位数的概念):

>>int('0b111111111111111111111111111111111011',2)
68719476731
>>int('-0b111111111111111111111111111111111011',2)
-68719476731

然而数字在计算机中是以补码保存的,Python位运算也是作用在补码上。

对于原码和补码,要知道正数的补码是它本身,负数的补码是它的反码末位加1。正数和负数的二进制表示都是他们的补码形式。

位运算:

对于正数,右移n位,在最左边补n个0;对于负数,右移n位,在最左边补n个1。


对于计算二进制中1的个数这道算法题来说,如果输入是负数的话,由于负数的补码最高位是1,以及右移特性,无论是右移还是n&(n-1)消除二进制数n最右边的1操作都不能将负数变为0,此时可以使用如下操作:

n = n & 0xffffffff

加入n=-5,执行上一步之后n=4294967291,

这步操作就是将负数n变为一个正数,而这个正数的补码正好和原来负数n的补码是一样的,但是这个正数的补码的操作右移最左边是补0的,n&(n-1)操作也能将最左边的1变位0,对最终计算二进制中1的个数没有影响。


总结n = n & 0xffffffff 这步操作将负数转换为正数,而这个正数的二进制编码正好和32位的负数的二进制编码长的一样,但是对其进行操作却没有对负数的二进制操作那么多限制。

评论

Live Sex Cams Free