Is unsetting a single bit in flags safe with Python variable-length integers? Is unsetting a single bit in flags safe with Python variable-length integers? python python

Is unsetting a single bit in flags safe with Python variable-length integers?


You should be safe using that approach, yes.

~ in Python is simply implemented as -(x+1) (cf. the CPython source) and negative numbers are treated as if they have any required number of 1s padding the start. From the Python Wiki:

Of course, Python doesn't use 8-bit numbers. It USED to use however many bits were native to your machine, but since that was non-portable, it has recently switched to using an INFINITE number of bits. Thus the number -5 is treated by bitwise operators as if it were written "...1111111111111111111011".

In other words, with bitwise-and & you're guaranteed that those 1s will pad the length of ~FLAG (a negative integer) to the length of status. For example:

  100000010000 # status&       ~10000 # ~FLAG

is treated as

  100000010000& 111111101111= 100000000000 # new status 

This behaviour is described in a comment in the source here.


Clearing a flag works with

status &= ~FLAG_THREE

because Python treats those negated values as negative:

>>> ~1L-2L>>> ~1-2>>> ~2-3

Thus the & operator can act appropriately and yield the wanted result irrespective of the length of the operands, so 0b11111111111111111111111111111111111111111111111111111111111 & ~1 works fine although the left hand operand is biffer than the right hand one.

In the other direction (RH longer than LH), it works nevertheless, because having an excess number of 1 bits doesn't matter.