How do I manipulate bits in Python?

In C I could, for example, zero out bit #10 in a 32 bit unsigned value like so:

unsigned long value = 0xdeadbeef; value &= ~(1<<10); 

How do I do that in Python ?

9 Answers

Bitwise operations on Python ints work much like in C. The &, | and ^ operators in Python work just like in C. The ~ operator works as for a signed integer in C; that is, ~x computes -x-1.

You have to be somewhat careful with left shifts, since Python integers aren't fixed-width. Use bit masks to obtain the low order bits. For example, to do the equivalent of shift of a 32-bit integer do (x << 5) & 0xffffffff.

value = 0xdeadbeef value &= ~(1<<10) 

Some common bit operations that might serve as example:

def get_bit(value, n): return ((value >> n & 1) != 0) def set_bit(value, n): return value | (1 << n) def clear_bit(value, n): return value & ~(1 << n) 

Usage e.g.

>>> get_bit(5, 2) True >>> get_bit(5, 1) False >>> set_bit(5, 1) 7 >>> clear_bit(5, 2) 1 >>> clear_bit(7, 2) 3 

You should also check out BitArray, which is a nice interface for dealing with sequences of bits.

Omit the 'unsigned long', and the semi-colons are not needed either:

value = 0xDEADBEEF value &= ~(1<<10) print value "0x%08X" % value 

Python has C style bit manipulation operators, so your example is literally the same in Python except without type keywords.

value = 0xdeadbeef value &= ~(1 << 10) 

Have you tried copying and pasting your code into the Python REPL to see what will happen?

>>> value = 0xdeadbeef >>> value &= ~(1<<10) >>> hex (value) '0xdeadbaef' 

If you're going to do a lot of bit manipulation ( and you care much more about readability rather than performance for your application ) then you may want to create an integer wrapper to enable slicing like in Verilog or VHDL:

 import math class BitVector: def __init__(self,val): self._val = val def __setslice__(self,highIndx,lowIndx,newVal): assert math.ceil(math.log(newVal)/math.log(2)) <= (highIndx-lowIndx+1) # clear out bit slice clean_mask = (2**(highIndx+1)-1)^(2**(lowIndx)-1) self._val = self._val ^ (self._val & clean_mask) # set new value self._val = self._val | (newVal<<lowIndx) def __getslice__(self,highIndx,lowIndx): return (self._val>>lowIndx)&(2L**(highIndx-lowIndx+1)-1) b = BitVector(0) b[3:0] = 0xD b[7:4] = 0xE b[11:8] = 0xA b[15:12] = 0xD for i in xrange(0,16,4): print '%X'%b[i+3:i] 

Outputs:

 D E A D 
1
a = int('00001111', 2) b = int('11110000', 2) bin(a & b)[2:].zfill(8) bin(a | b)[2:].zfill(8) bin(a << 2)[2:].zfill(8) bin(a >> 2)[2:].zfill(8) bin(a ^ b)[2:].zfill(8) int(bin(a | b)[2:].zfill(8), 2) 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like