ebalcsk
ebalcsk

Reputation: 33

What's the most efficient way to compare 2 numbers (16bit) bit by bit in Python?

I wonder what would be the most efficient way to compare 2 number (16bit) bit by bit in python? The order of the comparison does not matter.

In pseudo code I need something like this:

IF NUMBER1_BIT1 !=  NUMBER2_BIT1    THEN do something
IF NUMBER1_BIT2 !=  NUMBER2_BIT2    THEN do something 
IF NUMBER1_BIT3 !=  NUMBER2_BIT3    THEN do something 
…..
IF NUMBER1_BIT16 !=  NUMBER2_BIT16 THEN do something 

This part of my program will be executed a lot so I want to be as efficient as python can allow it.

Upvotes: 2

Views: 1375

Answers (3)

smac89
smac89

Reputation: 43206

Sounds like you are creating a bit mask. It is very common to see this done in C with 32 bit numbers and each bit is represented by a constant.

The cool thing about this method is that the mask will only produce some output if the bit is set in the input, otherwise the output will be 0.

Anyways, this is not C; this is python, so we can use the bin(x) method to convert each number to binary string, then compare each character in the string.

b_num1 = bin(num1).replace('0b', '')
b_num2 = bin(num2).replace('0b', '')

for i in range(num1.bit_length()):
    if b_num1[i] != b_num2[i]:
        pass # do something
    ...

Edit

In python3, we can use f-strings to create the binary numbers:

b_num1 = f'{num1:b}'
b_num2 = f'{num2:b}'

Upvotes: 0

Alain T.
Alain T.

Reputation: 42133

You could convert this into a switch-statement using a helper function:

def bitSwitch(v): yield lambda b: v & (1<<b)

Which you could then use like this:

for case in bitSwitch(number1 ^ number2):
    if case(0): 
       # do something ...

    if case(1):
       # do something else ...

    if case(2):
       # do some other thing ...

    if case(3):
       # do something different ...

    ...

    if case(15):
       # do that last thing ...

To be more efficient, you could replace v & (1<<b) with just v & b in the switch function and use the pre-computed powers of 2 in the case(..) calls: case(1): case(2) case(4) case(8) ... At that point napuzba's solution will be better because it does the same thing with less function call overhead.

Upvotes: 0

napuzba
napuzba

Reputation: 6298

You can use xor and and operators:

num3 = num1 ^ num2
if num3 & 1: # bits 0 are different
    ...
if num3 & 2: # bits 1 are different
    ...
if num3 & 4: # bits 2 are different
    ...

Upvotes: 1

Related Questions