【问题标题】:Understanding bitwise NOT in python在python中理解按位NOT
【发布时间】:2022-07-21 01:23:32
【问题描述】:
我试图在 python 中按位不理解。
我尝试了以下操作:
print('{:b}'.format(~ 0b0101))
print(~ 0b0101)
输出是
-110
-6
我试图理解输出如下:
按位取反 0101 得到 1010。在最高有效位中使用1,python 将其解释为 2 的补码形式的负数,并返回相应的小数,它进一步采用 1010 的 2 的补码,如下所示:
1010
0101 (negating)
0110 (adding 1 to get final value)
所以它打印为-110,相当于-6。
我对这种解释是否正确?
【问题讨论】:
标签:
python
bit-manipulation
bitwise-operators
【解决方案1】:
你说对了一半..
值确实是用~x == -(x+1)表示的(加一反码),但解释为什么有点误导。
Two 的补码数字需要设置整数的 MSB,如果数字可以是任意位数长(如 python 的情况),这有点困难。在内部,python 保留一个单独的数字(但是有对短数字的优化)来跟踪数字的长度。当您使用二进制格式print 一个负整数:f'{-6:b} 时,它只是在正值的二进制表示(一个恭维)前面打一个负号。否则,python 将如何确定应该有多少个领先的?正值是否应该总是有前导零来表示它们是正值?不过在内部,它确实确实使用了二进制的恭维。
如果我们在 2 的恭维中考虑带符号的 8 位数字(并显示所有数字),您的示例将变为:
~ 0000 0101: 5
= 1111 1010:-6
简而言之,python 正在执行正确的按位求反,但是负二进制格式数字的显示具有误导性。
【解决方案2】:
Python 整数是任意长的,因此如果将 0b0101 取反,则为 1111...11111010。你写几个?嗯,一个 4 位二进制补码 -6 是 1010,一个 32 位二进制补码 -6 是 11111111111111111111111111111010。因此,理想情况下,任意长的 -6 可以写成 -6。
检查当 ~5 被屏蔽以查看它所代表的位时会发生什么:
>>> ~5
-6
>>> format(~5 & 0xF,'b')
'1010'
>>> format(~5 & 0xFFFF,'b')
'1111111111111010'
>>> format(~5 & 0xFFFFFFFF,'b')
'11111111111111111111111111111010'
>>> format(~5 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,'b')
'11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111010'
负十进制表示是有意义的,您必须屏蔽以将表示限制为特定位数。