Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 705
elzell Avatar asked Jan 18 '16 13:01

elzell


People also ask

What is bit length in python?

int.bit_length()Returns the number of bits required to represent an integer in binary, excluding the sign and leading zeros.

How do you store bits in a variable?

If you want to use bits, you can build it up yourself like this: unsigned int key = (1<<9)|(1<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(1<<0);

Which Bitwise operation would you use if you need to set certain bits of a binary value?

Setting a bit Use the bitwise OR operator ( | ) to set a bit. number |= 1UL << n; That will set the n th bit of number . n should be zero, if you want to set the 1 st bit and so on upto n-1 , if you want to set the n th bit.

How do you remove a bit in Python?

*/ Step 1 : first convert the number into its binary form using bin(). Step 2 : remove the first two character. Step 3 : then extracting k bits from starting position pos from right.so, the ending index of the extracting substring is e=len(bi)-pos and starting index=e-k+1 Step 4 : extract k bit sub-string.


1 Answers

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.

like image 93
Alex Riley Avatar answered Sep 28 '22 08:09

Alex Riley