I'm trying to represent an integer as a list of bits and left pad it to 8 bits only if the integer is < 128:
Example input: 0x15
Desired output: [0, 0, 0, 1, 0, 1, 0, 1]
I do it in the following way:
input = 0x15
output = deque([int(i) for i in list(bin(input))[2:]])
while len(output) != 8:
output.appendleft(0)
I would like to convert any integer to a binary-list. Pad to 8 only if the number requires less than 8 bits to represent.
Another Example input: 0x715
Desired output: [1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1]
How can I do this both for numbers less then 8 bits and also for larger ones?
Integer, 16 bit Unsigned data type is used for numerical tags where only positive variables will be used.
In Python, we can simply use the bin() function to convert from a decimal value to its corresponding binary value. The bin() takes a value as its argument and returns a binary equivalent. Note: bin() return binary value with the prefix 0b, so depending on the use-case, formatting should be done to remove 0b.
Use the join() method of Python. First convert the list of integer into a list of strings( as join() works with strings only). Then, simply join them using join() method. It takes a time complexity of O(n) .
The most Pythonic way to convert a list of integers ints to a list of strings is to use the one-liner strings = [str(x) for x in ints] . It iterates over all elements in the list ints using list comprehension and converts each list element x to a string using the str(x) constructor.
num = 0x15
out = [1 if num & (1 << (7-n)) else 0 for n in range(8)]
The (1 << (7-n))
creates a single bit mask for a given position, and then bitwise &
tests to see if that bit is set in the number. Having n
work through 0 to 7 results in all 8 bits in the byte being tested in order.
import math
num = 0x715
bits = int(max(8, math.log(num, 2)+1))
out = [1 if num & (1 << (bits-1-n)) else 0 for n in range(bits)]
>>> [int(n) for n in bin(0x15)[2:].zfill(8)]
[0, 0, 0, 1, 0, 1, 0, 1]
The slice [2:]
is to remove 0b
prefix, zfill(8)
is to pad zeros on the left.
number = 0x15
output = [int(x) for x in '{:08b}'.format(number)]
'{:08b}'.format(number)
represents your number
in binary
format with 0 padding to 8 digits, then using list comprehension to create a list of bits.
Alternatively, you can use map
function:
output = map(int, '{:08b}'.format(0x15))
If you want to use a variable number of bits, here is one way:
width = 8 # 8bit width
output = [int(x) for x in '{:0{size}b}'.format(0x15, size=width)]
output = map(int, '{:0{size}b}'.format(0x15, size=width))
For Python 3, wrap the map(...)
call with list()
(map
returned a list in Python 2 but returns an iterator in 3).
Works for any number of bits, faster than the accepted answer and the current highest voted answer:
num = 0xAAAA
bit_list = [(num >> shift_ind) & 1
for shift_ind in range(num.bit_length())] # little endian
bit_list.reverse() # big endian
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
from timeit import timeit
def accepted_answer(number):
output = [int(x) for x in '{:08b}'.format(number)]
return output
def highest_voted_answer(num):
out = [1 if num & (1 << (7-n)) else 0 for n in range(8)]
return out
def this_answer(num):
bit_list = [(num >> shift_ind) & 1
for shift_ind in range(num.bit_length())] # little endian
bit_list.reverse() # big endian
return bit_list
NUM = 0x15
ITERATIONS = int(1e7)
print(timeit(lambda: accepted_answer(NUM), number=ITERATIONS))
print(timeit(lambda: highest_voted_answer(NUM), number=ITERATIONS))
print(timeit(lambda: this_answer(NUM), number=ITERATIONS))
9.884788331000891
9.262861715000327
6.484631327999523
It's easy to do this with format strings
>>> "{:08b}".format(0x15)
'00010101'
>>> "{:08b}".format(0x151)
'101010001'
>>> "{:08b}".format(0x1511)
'1010100010001'
to convert to a list
>>> [1 if x=='1' else 0 for x in "{:08b}".format(0x15)]
[0, 0, 0, 1, 0, 1, 0, 1]
>>> [1 if x=='1' else 0 for x in "{:08b}".format(0x1511)]
[1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]
It's likely to be faster using bit twiddling as in @Amber's answer, but then you'll have to check for special cases and end up with quite a bit of code. If utmost performance isn't required, it's safer to build on what you know already works
np.unpackbits(np.frombuffer(number, np.dtype('B')))
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