Python Bitwise ~ Operator

Question:

Several previously asked questions such as this and this mention only why this happens i.e. 2’s compliment.
I need help with how to convert this :

print("if ~(0b11011111) is "+str(bin(~(0b1101111))) +" not 0b00100000")
print("and ~(0b00100000) is  " +str(bin(~(0b00100000)))+" not 11011111")

Output :

if ~(0b11011111) is -0b1110000 not 0b00100000
and ~(0b00100000) is  -0b100001 not 11011111

Can anyone help me with how to do this?

Answers:

When you have a fixed number of bits, inverting them is easy — just invert them. So, for example, it we are working with 4-bit integers, the inverse of 5 (0b0101) is 0b1010

However, Python has arbitrary-sized integers, which makes things a bit tricker. If we invert 5 (0b101), is the result 1010 or 11111010 or 1111111111111010 or what? So Python defines inverting in terms of integers (in the mathematical sense, as opposed to strings of bits); ~x ≝ -(x+1). Why this definition? When working with two’s-complement representation of negatives, neg(x) = inv(x)+1 so it makes sense that inv(x) = neg(x)-1 = -(x+1). This is why ~5 comes out to -6.

So that is why you are getting negative numbers, but how do you get the positive value that you expect? The language spec does not say it explicitly, but the bitwise & and | operators seem to treat negatives as having “enough” ones on the left. This means that if you mask out only as many bits to the right as you want, you get a positive number. For example, if we want to invert a 4-bit number 5, we can do bin(~0b101 & 0b1111 and get the expected 0b1010.

You seem to be expecting 8-bit numbers, so for example bin(~0b00100000 & 0xff) gives you 0b11011111.

Answered By: Ture Pålsson
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.