python bitwise operations

Bit Shifting

The code is a demo for what happens with >> and <<.

OffOn=int('10101010', 2)
pprint(OffOn)
orig="{:08b}".format(OffOn)
for n in range(0,8):
    left_shift= OffOn << n
    bleft_shift="{:08b}".format(OffOn << n)
    right_shift= OffOn >> n
    bright_shift = "{:08b}".format(OffOn >> n)
    print("Shift {:3d} {} L {:16s} R {:16s}  L {:12d}  R {:12d}".format(n,orig,bleft_shift,bright_shift,left_shift,right_shift))

Output for this test is

170
Shift   0 10101010 L 10101010         R 10101010          L          170  R          170
Shift   1 10101010 L 101010100        R 01010101          L          340  R           85
Shift   2 10101010 L 1010101000       R 00101010          L          680  R           42
Shift   3 10101010 L 10101010000      R 00010101          L         1360  R           21
Shift   4 10101010 L 101010100000     R 00001010          L         2720  R           10
Shift   5 10101010 L 1010101000000    R 00000101          L         5440  R            5
Shift   6 10101010 L 10101010000000   R 00000010          L        10880  R            2
Shift   7 10101010 L 101010100000000  R 00000001          L        21760  R            1

So

    • Makes the bit object Shift one to the right and become 0 filled.
  • <<
    • makes the bit object sift to the right. And the LSB becomes 0

Bit Masking

With the << operation the number gets much bigger.

For example

  • decimal 10880
  • Binary 10101010000000

But what are the LSB 8 bit values ...

I can cut them using a [:-8] is they were a string... but that is ugly.

eight_lsb_bits = (21760 & 0xFF)

Which gives the result of 128 ... which is what the last 8 bits are 10000000

8 Bit to 7 Bit

This is just a variation of the previous step.

Lets start with 8 bits

on_off=int('10101010',2)
pprint(on_off)

Gives 170

Lets convert to 7 Bit by loosing the MSB i.e. in array terms [0]

We know this bit string should now look like this

  • orig
    • 10101010
  • new
    • 0101010
int('10101010',2)&(0x7f)

Which gives 42.... which is '101010' => 32+8+2

So why 0x7f ?

We want to generate a mask of 01111111

  • binary 01111111
  • decimal 127
  • hex 0x7f

A one liner would be

hex(int('01111111',2))

Which yields 0x7f.

Bit Combining

I want to combine 4 Bits from 1 int with 4 bits of the 2nd int.

  • a
    • 11100000
  • b
    • 00001010

So a[:4]b[:-4] should be **11101010'

We need to use the | operator.

int1 | int2

Select first 4 Bits

To select the first 4 bits - we need a mask of 11110000 which is 128+64+32+16 => 240

a=int('11100000',2)
b=int('00001010',2)
mask1=int('11110000',2)
first_part=a & mask1

Which gives 224 ... 11100000 (128+64+32)

Select the last 4 bits

The last 4 bits are bits 00001111 so this needs a mask of 1111 which is 8+4+2+1->15->0x0f

All in 1

I want to combine 4 Bits from 1 int with 4 bits of the 2nd int.

a=int('11100000',2)
b=int('00001010',2)
mask1=int('11110000',2)
mask2=int('00001111',2)

res = a & mask1 | b&mask2

Which gives 234.... to double check we manually compute int('11101010',2)

Bit Chopping

I need to chop some bits....

a=int('01101001',2)


#first 2 bits 64=64
#last  2 bits 1=1
#first 3 bits 64+32=96
#last  3 bits 1=1
#first 4 bits 64+32=96
#last  4 bits 8+1=9
#first 4 bits 64+32=96
#last  4 bits 8+1=9
#first 5 bits 64+32+8=104
#last  5 bits 8+1=9



def last_n_bits(number,last_bytes):
    return number&(0xff>>(8-last_bytes))

def first_n_bits(number,first_bytes):
    return number&(0xff>>8-first_bytes<<8-first_bytes)

print(last_n_bits(a,2))
print(first_n_bits(a,2))
print(last_n_bits(a,3))
print(first_n_bits(a,3))
print(last_n_bits(a,4))
print(first_n_bits(a,4))
print(last_n_bits(a,5))
print(first_n_bits(a,5))

You should see output like

1
64
1
96
9
96
9
104