1

This answer demonstrates the negation of the LSB of an integer. This approach did not produce expected results when using negative (signed) integers. Let's look at some code:

a = 4

print()
print("a: " + str(a))
print("binary version of a: " + bin(a))

a = a | 1

print("binary version of a after negation of LSB: " + bin(a))
print("a after negation of LSB: " + str(a))
print()

b = 5

print("b: " + str(b))
print("binary version of b: " + bin(b))

b = b & ~1

print("binary version of b after negation of LSB: " + bin(b))
print("b after negation of LSB: " + str(b))
print()

c = -4

print("c: " + str(c))
print("binary version of c: " + bin(c))

c = c | 1

print("binary version of c after negation of LSB: " + bin(c))
print("c after negation of LSB: " + str(c))
print()

d = -5

print("d: " + str(d))
print("binary version of d: " + bin(d))

d = d & ~1

print("binary version of d after negation of LSB: " + bin(d))
print("d after negation of LSB: " + str(d))

The expected value of c after the negation of the LSB is -5 and not -3. Similarly, the expected value of d after the negation of the LSB is -4 and not -6. Why don't the actual values of c and d match their expected values?

Luka Banfi
  • 111
  • 8

1 Answers1

1

I think the problem here is python stores negative numbers as their two's complement, but doesn't print them out that way. Makes things pretty confusing! This post here goes into more detail about it, but we can see what's going on with a quick example:

-4 in binary is 0b11111100 (two's complement of 4)

1 is positive so in binary it is just 0b00000001

When you or those two together, you get:

0b11111101 which is the binary representation of -3 (two's complement)

I used this site to find the two's complements, and it's worth noting that python integers are 32 bits instead of 8, so there will be 24 extra 1's in front of the negative/two's complement numbers and 24 extra 0's in front of the positive numbers (well as long as both are below abs(255))

  • To be more precise, your [linked answer](https://stackoverflow.com/questions/46993519/python-representation-of-negative-integers) states "CPython integer type stores the sign in a specific field of a structure. When performing a bitwise operation, CPython replaces negative numbers by their two's complement [...]". Although not in the question, it is interesting that you can't flip the MSB to turn the sign, because the bit width of Python's integer is flexible. Try `2**500`! Very special implementation. – John Jun 29 '22 at 08:04