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

elzell :

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.)

Alex Riley :

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.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related