Reputation: 3317
I was recently going over bit shifting and was wondering why in the below iPython output, shifting the value -1 vs shifting the value 4294967295 yielded different results?
In [30]: val = -1
In [31]: print "hex x %d 0x%08X" % (val, val & 0xffffffff)
hex x -1 0xFFFFFFFF
In [32]: val = val >>22
In [33]: print "hex x %d 0x%08X" % (val, val & 0xffffffff)
hex x -1 0xFFFFFFFF
In [34]: val = 4294967295
In [35]: print "hex x %d 0x%08X" % (val, val & 0xffffffff)
hex x 4294967295 0xFFFFFFFF
In [36]: val = val >>22
In [37]: print "hex x %d 0x%08X" % (val, val & 0xffffffff)
hex x 1023 0x000003FF
I would really appreciate any clarification, thanks.
Upvotes: 3
Views: 3955
Reputation: 61643
Short version: Because the operation is defined that way.
Long version: per the documentation, "The rules for integer representation are intended to give the most meaningful interpretation of shift and mask operations involving negative integers." In a system where numbers can be arbitrarily sized but have 2s complement representation, it follows that - at least conceptually - the sign extension carries arbitrarily far as well. So this is really the only interpretation that makes sense.
This preserves the invariant that x >> n
<=> int(x / (2 ** n))
across the negative numbers as well.
Upvotes: 2
Reputation: 308530
When a negative number is used in an expression, by the rules of two's complement arithmetic the sign bit must be extended all the way to the left bit of the expression. A right shift is preserving those left-most 1 bits. A negative number shifted right by a sufficient number of bits will always equal -1, just as a positive number shifted right by a sufficient number of bits will always equal 0.
Upvotes: 1
Reputation: 799390
4294967295 is 0x0...0FFFFFFFF. -1 is 0xF...FFFFFFFF. Forever.
Upvotes: 2