Python supports arbitrary bit-length integers, but I would like to emulate int32, 32-bit integers, in all their overflow glory.
I have few questions and comments about this
int32hasINT32_MIN = -(1 << 31)andINT32_MAX = (1 << 31) - 1- Does python use 2's complement?
- in
int32, a positiveint32has leading zeros up to the 31st bit and a negativeint32has leading ones up to the 31st bit (this is because they are 2's complement). - in python, a positive integer is considered to have infinitely (or arbitrarily) many leading ones and a negative integer is considered to have infinitely (or arbitrarily) many leadings ones.
So for example:
123 would look like:
0b0000_0000_0000_0000_0000_0000_0111_1011inint320b...0_0111_1011in python (...0indicates infinitely many leading0's)
-123 would look like:
0b1111_1111_1111_1111_1111_1111_1000_0101inint320b...1_1000_0101in python (...1indicates infinitely many leading1's)
Given all this, I've come up with this code to emulate int32, but would like a check:
INT32_MIN = -(1 << 31)
INT32_MAX = (1 << 31) - 1
INT32_MASK = (1 << 32) - 1
INT32_SIGNBIT = 1 << 31
def int32(x):
sb = bool(x & INT32_SIGNBIT)
i32 = x & INT32_MASK
if sb:
i32 += ~INT32_MASK
return i32
a = int32(INT32_MAX + 1)
b = int32(INT32_MIN - 1)
aa = a == INT32_MIN
bb = b == INT32_MAX
It does seem to overflow as desired when you add 1 to INT32_MAX or subtract 1 from INT32_MIN, so that gives me some confidence that it is correct, but that's just two test cases. Does this look correct to you?
It looks correct, and your understanding of two's complement integers and Pythons take on them is also correct. The implementation can be simplified, for some definition of simplification (maybe it's more difficult to grasp).
Alternatively it could be done like this:
The first line is obvious, the second line performs sign-extension by flipping the sign with an XOR and then flipping it back with a subtraction which will also set the infinite leading bits if necessary.