bitwise not - not what I expected

Tim Peters tim.one at comcast.net
Sun Aug 17 01:35:47 EDT 2003


[Elaine Jackson]
> Is there a function that takes a number with binary numeral a1...an
> to the number with binary numeral b1...bn, where each bi is 1 if ai
> is 0, and vice versa? (For example, the function's value at 18
> [binary 10010] would be 13 [binary 01101].) I thought this was what
> the tilde operator (~) did,

Surprise:  that is what ~ does.

> but when I went to try it I found out that wasn't the case.

Please give a specific example.  To understand your example above, note that
binary 10010 actually has an unbounded number of 0 bits "to the left":

    ...00000010010 = 13

The bitwise inversion of that therefore has an unbounded number of 1 bits
"to the left":

    ...11111101101 = -19

This is why you get -19:

>>> n = 18
>>> ~n
-19
>>>

Any answer other than that is wishing away the 0 bits at the left in the
input.  Python can't *guess* how many bits you want to keep.  If you only
want to keep the rightmost 5 bits, then explicitly mask off the rightmost 5
bits:

>>> (~18) & 0x1f
13
>>>

So that's the 13 "you expected".

> I discovered by experiment (and verified by looking at the
> documentation) that the tilde operator takes n to -(n+1). I can't
> imagine what that has to do with binary numerals. Can anyone
> shed some light on that?

Python represents negative integers in unbounded 2's-complement form (well,
it doesn't really under the covers, but it maintains the illusion of doing
so in all arithmetic and logical operators).  The 2's-complement of an
integer is equal to 1 plus its 1's-complement form, and 1's-complement is
identical to bitwise inversion.  So

    -n = 1 + (~n)

Then

    ~n = -(n+1)

follows from that via rearrangement.

> (In case you're curious, I'm writing a script that will play Nim,
> just as a way of familiarizing myself with bitwise operators. Good
> thing, too: I thought I understood them, but apparently I don't.)

You're only overlooking the consequences of an infinite amount of
information <wink>.






More information about the Python-list mailing list