代码之家  ›  专栏  ›  技术社区  ›  user9505617

按位异或0xFFFFFFFF?

  •  1
  • user9505617  · 技术社区  · 7 年前

    我无法理解这一点:

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

    我明白了 ~a 表示2的补码 a 但是 a ^ 0xFFFFFFFF 也会翻转所有位,但python会将其解释为一个大数字。我知道Python3使用的是未绑定的整数大小,这是如何工作的?有人能像我五岁那样解释吗?

    结果:

    (         -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 回复  |  直到 7 年前
        1
  •  2
  •   Kevin    7 年前

    在Python中,整数大小是无限的,如何用二进制表示-1?111。。。1是一个大的正整数,不是吗?

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

    Python将这个概念扩展到负数,表示负数的前导数是无限的 一个 。所以如果你需要代表-37,那就是。。。111011011,前面需要多少就有多少。类似地,-1只是。。。所以如果用另一个Python整数对-1进行异或运算,它会翻转 全部的 该数字的位,包括其前导的0或1(就像使用了tilde运算符一样)。不幸的是,Python没有方便的二进制表示法来表示“无限前导数”,因此您无法编写(例如) 0b...111 作为整数文本;您必须使用 -1 相反,或将其反转并写入 ~0b0

    虽然这听起来很荒谬,但实际上在数学上是合理的。在 2-adic numbers ,这些前导数为无穷大的序列形式上等价于相应的负整数。如果您更喜欢一种更扎根于计算机工程的方法,您可以想象Python会自动进行整数运算 sign-extend 无论它们需要多宽(这或多或少是实际的实现)。

        2
  •  1
  •   Wolf    5 年前

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