按位xor 0xFFFFFFFF?

时间:2018-03-16 23:55:59

标签: python-3.x bit-manipulation xor twos-complement

我无法绕过这个:

def expr(a):
    return ~(a ^ 0xFFFFFFFF), a ^ 0xFFFFFFFF, ~a, a

print(expr(0xFFFFFFFF))
print(expr(1))
print(expr(0))  
print(expr(-1))

我理解~a表示a的两个补码,但a ^ 0xFFFFFFFF也会翻转所有位,但python会将其解释为大数。我知道Python3使用的是未绑定的整数大小,它是如何工作的?有人可以ELI5(解释就像我是五个人)吗?

结果:

(         -1,           0, -4294967296, 4294967295)
(-4294967295,  4294967294,          -2,          1)
(-4294967296,  4294967295,          -1,          0)
( 4294967295, -4294967296,           0,         -1)

更新 我想我的问题可以简化为:在C中​​,111 ... 1可以表示-1,我得到了这个,因为它是32位。在Python中,整数大小是无限的,你如何在二进制中表示-1? 111 ... 1是一个大的正整数,没有?

2 个答案:

答案 0 :(得分:0)

0xFFFFFFFF是一个很大的数字;它是2 32 -1的十六进制表示。 Python的内部在内部表示为C long的链表,允许理论上无限大小。 Python中的按位XOR(^)对于比您给出的位更重要的位使用零值,因此最终结果是只有低32位被翻转,导致行为与您在C中得到的行为不同,只有32位,最终结果是“全部”。这些位被翻转。

答案 1 :(得分:0)

  

在Python中,整数大小是无限的,你如何在二进制中表示-1? 111 ... 1是一个大的正整数,没有?

正数具有无限的前导零序列。也就是说,如果我们需要表示数字100101(等于37),那等于... 000100101,前面有你想要的零。没有计算机系统试图存储所有这些前导零,因为存在无限多个,但是可能存储一些前导零以便将数字填充到合理的"大小,例如32或64位。

Python将这个概念扩展为负数,称它们具有无限数量的前导 1 。因此,如果你需要代表-37,那将是...... 111011011,你需要的数量与前面一样多。同样,-1只是...... 1111。因此,如果您使用另一个Python整数XOR -1,它将翻转该数字位的所有,包括其前导零或1(就像您使用了波浪号运算符一样)。不幸的是,Python没有一个方便的二进制表示法,用于"无限领先的表达式,"所以你不能写(例如)0b...111作为整数文字;您必须使用-1代替,或将其反转并撰写~0b0

虽然这可能听起来很荒谬,但实际上它在数学上是合理的。在2-adic numbers下,具有无限前导序列的这些序列在形式上等同于相应的负整数。如果你更喜欢一种更基于计算机工程的方法,你可能会想象Python整数自动sign-extend到它们需要的宽度(这或多或少是实际的实现)。