我无法绕过这个:
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是一个大的正整数,没有?
答案 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到它们需要的宽度(这或多或少是实际的实现)。