-2

Here are my code and wondering why different results in both cases? Actually I expect first line output -1, since bit AND 0xffffffff does not change anything. And I expect second line output 1, since bit XOR 0xffffffff means bit NOT (which is ~ in Python, and adding another 1 should gets -1's two's complement value, which is 1)

print -1 & 0xffffffff # output 4294967295
print -1 ^ 0xffffffff + 1 # output -4294967297
Lin Ma
  • 9,739
  • 32
  • 105
  • 175
  • 1
    Python integer arithmetic is not 32-bit; it is infinite-bit. (It doesn't physically store an infinite number of bits, but it behaves like it does.) – user2357112 Aug 14 '17 at 21:52
  • @user2357112, I understand it is infinite like Java big integer, but how it comes to value 4294967295 in my first case and -4294967297 in my second case? – Lin Ma Aug 14 '17 at 21:55
  • 2
    Your reasoning is assuming 32-bit. Why do you think "bit AND 0xffffffff does not change anything"? Why do you think "bit XOR 0xffffffff means bit NOT"? – user2357112 Aug 14 '17 at 21:56
  • 1
    (If you tested this in Java and got -1 and 1, you most likely screwed up the precedence of `^` and `+` and the initialization of the 0xffffffff BigInteger. With correct precedence and avoiding overflow on 0xffffffff, [Java gives the same output](http://ideone.com/A8S8jf).) – user2357112 Aug 14 '17 at 22:04

1 Answers1

4

Python implements integers with arbitrary precision. When performing bit-wise operations, positive numbers are treated as if they have an infinite sequence of high-order 0 bits, while negative numbers act like they have an infinite sequence of high-order 1 bits. In particular, the number -1 acts like an infinite sequence of 1's.

So for the first calculation we have

    ...11111111111111111111111111111111111111111111111111111111
  & ...00000000000000000000000011111111111111111111111111111111
  = ...00000000000000000000000011111111111111111111111111111111

Since this has 0 in the high-order bits, it's a positive result.

The second calculation is:

    ...11111111111111111111111111111111111111111111111111111111
  ^ ...00000000000000000000000100000000000000000000000000000000 (this is 0xffffffff + 1 = 0x100000000)
  = ...11111111111111111111111011111111111111111111111111111111

Since this has 1 in the high-order bits, it's a negative result.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 2
    That doesn't yet explain the outcome in full. Note that [`+` binds stronger than `^`](https://docs.python.org/2/reference/expressions.html#operator-precedence) in Python, hence the second example reduces to `-1 ^ 0x100000000`. – dhke Aug 14 '17 at 22:06
  • 1
    Thanks, missed the `+1`. I've updated the answer to show that. – Barmar Aug 14 '17 at 22:09
  • 2
    @dhke Also corrected the number of low-order digits. – Barmar Aug 14 '17 at 22:10
  • 1
    32bits are really A LOT when one needs to type them out. – dhke Aug 14 '17 at 22:13
  • Thanks for the help Barmar, mark your reply as answer. – Lin Ma Aug 14 '17 at 23:27