【问题标题】: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

我对这种解释是否正确?

【问题讨论】:

  • 是的,或多或少...implementation 中的注释表示逻辑输出为~x as -(x+1)

标签: 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'
    

    负十进制表示是有意义的,您必须屏蔽以将表示限制为特定位数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-05-19
      相关资源
      最近更新 更多