How do I manipulate bits in Python?

34

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 ?

python
asked on Stack Overflow Sep 29, 2008 by Eden

9 Answers

49

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.

answered on Stack Overflow Sep 29, 2008 by Fredrik Johansson • edited Apr 20, 2018 by heemayl
11
value = 0xdeadbeef
value &= ~(1<<10)
answered on Stack Overflow Sep 29, 2008 by Greg Hewgill
5

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
answered on Stack Overflow Apr 20, 2018 by Boern
4

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

answered on Stack Overflow Sep 30, 2008 by user19883
3

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'
answered on Stack Overflow Sep 29, 2008 by John Millikin
3

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

value = 0xDEADBEEF
value &= ~(1<<10)
print value
"0x%08X" % value
answered on Stack Overflow Sep 29, 2008 by Jonathan Leffler
3

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)
answered on Stack Overflow Sep 29, 2008 by Martin W
1

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
answered on Stack Overflow Sep 29, 2008 by Ross Rogers
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)
answered on Stack Overflow Aug 8, 2017 by witold-gren

User contributions licensed under CC BY-SA 3.0