How can I iterate and evaluate the value of each bit given a specific binary number in python 3?
For example:
00010011 
--------------------
bit position | value
--------------------
[0]            false (0)
[1]            false (0)
[2]            false (0)
[3]            true  (1)
[4]            false (0)
[5]            false (0)
[6]            true  (1)
[7]            true  (1)
                If you don't know the least number of bits required to represent a number, you can do len(bin(number)) - 2 . bin(number) gives you 0b1010101 , so you get the string's length and take 2 out of it.
You can test for individual bits using bitwise operators and bit shifts. The part that must be new to you, is the >> operator. This operator will "insert a zero on the left and push every bit to the right, and the rightmost will be thrown away".
To loop through a set of code a specified number of times, we can use the range() function, The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and ends at a specified number.
This bit numbering method has the advantage that for any unsigned number the value of the number can be calculated by using exponentiation with the bit number and a base of 2. The value of an unsigned binary integer is therefore
Most significant bit first means that the most significant bit will arrive first: hence e.g. the hexadecimal number 0x12, 00010010 in binary representation, will arrive as the sequence 0 0 0 1 0 0 1 0 .
Rather, it is a property of the numeric value in binary itself. This is often utilized in programming via bit shifting: A value of 1 << n corresponds to the nth bit of a binary integer (with a value of 2 n ).
where bi denotes the value of the bit with number i, and N denotes the number of bits in total. When the bit numbering starts at zero for the most significant bit (MSB) the numbering scheme is called MSB 0 .
It's better to use bitwise operators when working with bits:
number = 19
num_bits = 8
bits = [(number >> bit) & 1 for bit in range(num_bits - 1, -1, -1)]
This gives you a list of 8 numbers: [0, 0, 0, 1, 0, 0, 1, 1]. Iterate over it and print whatever needed:
for position, bit in enumerate(bits):
    print '%d  %5r (%d)' % (position, bool(bit), bit)
                        Python strings are sequences, so you can just loop over them like you can with lists. Add enumerate() and you have yourself an index as well:
for i, digit in enumerate(binary_number_string):
    print '[{}] {:>10} ({})'.format(i, digit == '1', digit)
Demo:
>>> binary_number_string = format(19, '08b')
>>> binary_number_string
'00010011'
>>> for i, digit in enumerate(binary_number_string):
...     print '[{}] {:>10} ({})'.format(i, digit == '1', digit)
... 
[0]      False (0)
[1]      False (0)
[2]      False (0)
[3]       True (1)
[4]      False (0)
[5]      False (0)
[6]       True (1)
[7]       True (1)
I used format() instead of bin() here because you then don't have to deal with the 0b at the start and you can more easily include leading 0.
Surprisingly, converting the integer to a string is quite a bit faster than using binary operations. Benchmarking on a Core i9 running MacOS 10.15 with Python 3.7.6:
In [6]: number = 1 << 30
In [7]: num_bits = 32
In [8]: %timeit bits = [c == '1' for c in format(number, f'0{num_bits}b')]
1.84 µs ± 8.51 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [9]: %timeit bits = [(number >> bit) & 1 for bit in range(num_bits - 1, -1, -1)]
3.13 µs ± 69.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
The format() approach runs in 60% of the time of the bitwise operators approach! (Nor is it changed much if you add an if-else to get a list of integers instead of booleans.)
I assume this is because Python integers are stored behind the scenes in a way that doesn't allow for efficient bitwise operations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With