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

Question:

In my program (written in Python 3.4) I have a variable which contains various flags, so for example:

FLAG_ONE = 0b1
FLAG_TWO = 0b10
FLAG_THREE = 0b100
status = FLAG_ONE | FLAG_TWO | FLAG_THREE

Setting another flag can easily be done with

status |= FLAG_FOUR

But what if I explicitly want to clear a flag? I’d do

status &= ~FLAG_THREE

Is this approach safe? As the size of an integer in Python is not defined, what if status and FLAG_THREE differ in size?

(status needs to be a bit field because I need this value for a hardware protocol.)

Asked By: elzell

||

Answers:

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.

Answered By: glglgl

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.

Answered By: Alex Riley
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.