Converting a number to binary with a fixed length
Question:
Say I get a random number between 1 and 127. I change the number to binary and remove the 0b
from it with the following code:
key_one= int(raw_input("Enter key (0 <= key <= 127): "))
if key_one in range(128):
bin_key_one=bin(key_one)[2:]
print bin_key_one
else:
print "You have to enter key (0 <= key <= 127)"
Now I want to make it 7-characters long by padding the beginning with zeros as necessary. I think I need to use a for loop, but can someone show me how to do it?
Answers:
No you don’t.
>>> '{0:07b}'.format(12)
'0001100'
Try this:
for i in range(1, 127):
'0'*(7-len(bin(i)[2:]))+bin(i)[2:]
So it happens that Python has a string method .zfill()
for that:
>>> '1'.zfill(7)
'0000001'
>>> '10010'.zfill(7)
'0010010'
With Python 3.6’s new f-strings, you can now do:
key_one = int(input("Enter key (0 <= key <= 127): "))
if key_one in range(128):
bin_key_one = f'{key_one:07b}'
print(bin_key_one)
else:
print("You have to enter key (0 <= key <= 127)")
If you want variable length:
>>> n = 12
>>> l = 7
>>> bin(n)[2:].zfill(l)
'0001100'
Once for my project i needed to convert an integer to binary with variable length of binary string so i did
num_bits = 12
num = 4
f'{num:0{num_bits}b}'
Output
000000000100
You can use str.rjust
too if you want to be flexible on the character to use as padding rather than just 0
:
>>> s = '111'
>>> s.rjust(8, '0')
'00000111'
>>> s.rjust(8, 'x')
'xxxxx111'
In 2022 python 3.8, f strings can accomplish this with this code.
f'{your_number:07b}'
If you wanted to convert strings to fixed binary you could do this
to_bin = [f'{ord(i):07b}' for i in input_data]
You can also use any number equal or greater than 7. Say you wanted 24bit. The length should always be preceded by 0.
f'{9:024b}'
Output: 000000000000000000001001
Converting decimal to binary with desired significant digits and vice -versa
# Function returns decimal representation
def bin_float(binStr, places = 10):
if binStr.find('.') >= 0:
whole, dec = binStr.split(".")
else:
whole, dec = str(int(binStr)), '0'
x = 0
N = len(whole)-1
for k in range(N+1):
x += int(whole[N-k])*2**k
N = len(dec)
for k in range(N):
dx = int(dec[k])/2**(k+1)
x += dx
return(x)
# Function returns binary representation
def float_bin(x, places = 5):
# Convert an integer number to it's
# respective binary representation
if int(x) == x:
return('{:b}'.format(int(x)))
# Separate x to integer and decimal parts
# and store in two separate variables
whole = int(x)
dec = abs(x - whole)
# Convert the whole number part to it's
# respective binary representation
binStr = '{:b}'.format(whole)+'.'
# Check if |x| > 0 for needed significant digits
Sw = whole != 0
# Iterate for significant/decimal digits
Dig = 0
while (Dig < places):
# Multiply the decimal value by 2
# and separate the whole number part
# and decimal part
dec *= 2
whole = int(dec)
dec = abs(dec - whole)
# Keep adding the integer parts
# receive to the result variable
binStr += str(whole)
# Stating significant digit from non zero value
if Sw:
Dig += 1
else:
Sw = whole != 0
# if last digit is 1, need roundoff truncation
if binStr[-1] == '1':
k = len(binStr)-1
while (k > 0) and (binStr[k] in ['.', '1']):
if binStr[k] == '1':
binStr = binStr[:k]+'0'+binStr[k+1:]
k -= 1
if len(binStr)-1-k > places:
binStr = binStr[:k]+'1'+binStr[k+1:-1]
else:
binStr = binStr[:k]+'1'+binStr[k+1:]
return(binStr[:-1])
Test the code:
def do_for(x, p):
bx = float_bin(x, places = p)
Dx = bin_float(bx)
rel = 100*abs(1-Dx/x)
if rel >= 1:
print('n value = {:.6e} binary = {} ({} sig. digits)'.format(x, bx, p),
'n saved = {:.6e} Error = {:.2f}%'.format(Dx, rel))
else:
print('n value = {:.6e} binary = {} ({} sig. digits)'.format(x, bx, p),
'n saved = {:.6e} Error = {:.1e}%'.format(Dx, rel))
do_for(0.234, 8)
do_for(0.234, 3)
do_for(0.234, 2)
do_for(15/16, 4)
do_for(31/32, 4)
do_for(1.00052123, 12)
do_for(0.00052123, 8)
results:
value = 2.340000e-01 binary = 0.0011110000 (8 sig. digits)
saved = 2.343750e-01 Error = 1.6e-01%
value = 2.340000e-01 binary = 0.00111 (3 sig. digits)
saved = 2.187500e-01 Error = 6.52%
value = 2.340000e-01 binary = 0.010 (2 sig. digits)
saved = 2.500000e-01 Error = 6.84%
value = 9.375000e-01 binary = 0.1111 (4 sig. digits)
saved = 9.375000e-01 Error = 0.0e+00%
value = 9.687500e-01 binary = 1.000 (4 sig. digits)
saved = 1.000000e+00 Error = 3.23%
value = 1.000521e+00 binary = 1.00000000001 (12 sig. digits)
saved = 1.000488e+00 Error = 3.3e-03%
value = 5.212300e-04 binary = 0.000000000010001001 (8 sig. digits)
saved = 5.226135e-04 Error = 2.7e-01%
Say I get a random number between 1 and 127. I change the number to binary and remove the 0b
from it with the following code:
key_one= int(raw_input("Enter key (0 <= key <= 127): "))
if key_one in range(128):
bin_key_one=bin(key_one)[2:]
print bin_key_one
else:
print "You have to enter key (0 <= key <= 127)"
Now I want to make it 7-characters long by padding the beginning with zeros as necessary. I think I need to use a for loop, but can someone show me how to do it?
No you don’t.
>>> '{0:07b}'.format(12)
'0001100'
Try this:
for i in range(1, 127):
'0'*(7-len(bin(i)[2:]))+bin(i)[2:]
So it happens that Python has a string method .zfill()
for that:
>>> '1'.zfill(7)
'0000001'
>>> '10010'.zfill(7)
'0010010'
With Python 3.6’s new f-strings, you can now do:
key_one = int(input("Enter key (0 <= key <= 127): "))
if key_one in range(128):
bin_key_one = f'{key_one:07b}'
print(bin_key_one)
else:
print("You have to enter key (0 <= key <= 127)")
If you want variable length:
>>> n = 12
>>> l = 7
>>> bin(n)[2:].zfill(l)
'0001100'
Once for my project i needed to convert an integer to binary with variable length of binary string so i did
num_bits = 12
num = 4
f'{num:0{num_bits}b}'
Output
000000000100
You can use str.rjust
too if you want to be flexible on the character to use as padding rather than just 0
:
>>> s = '111'
>>> s.rjust(8, '0')
'00000111'
>>> s.rjust(8, 'x')
'xxxxx111'
In 2022 python 3.8, f strings can accomplish this with this code.
f'{your_number:07b}'
If you wanted to convert strings to fixed binary you could do this
to_bin = [f'{ord(i):07b}' for i in input_data]
You can also use any number equal or greater than 7. Say you wanted 24bit. The length should always be preceded by 0.
f'{9:024b}'
Output: 000000000000000000001001
Converting decimal to binary with desired significant digits and vice -versa
# Function returns decimal representation
def bin_float(binStr, places = 10):
if binStr.find('.') >= 0:
whole, dec = binStr.split(".")
else:
whole, dec = str(int(binStr)), '0'
x = 0
N = len(whole)-1
for k in range(N+1):
x += int(whole[N-k])*2**k
N = len(dec)
for k in range(N):
dx = int(dec[k])/2**(k+1)
x += dx
return(x)
# Function returns binary representation
def float_bin(x, places = 5):
# Convert an integer number to it's
# respective binary representation
if int(x) == x:
return('{:b}'.format(int(x)))
# Separate x to integer and decimal parts
# and store in two separate variables
whole = int(x)
dec = abs(x - whole)
# Convert the whole number part to it's
# respective binary representation
binStr = '{:b}'.format(whole)+'.'
# Check if |x| > 0 for needed significant digits
Sw = whole != 0
# Iterate for significant/decimal digits
Dig = 0
while (Dig < places):
# Multiply the decimal value by 2
# and separate the whole number part
# and decimal part
dec *= 2
whole = int(dec)
dec = abs(dec - whole)
# Keep adding the integer parts
# receive to the result variable
binStr += str(whole)
# Stating significant digit from non zero value
if Sw:
Dig += 1
else:
Sw = whole != 0
# if last digit is 1, need roundoff truncation
if binStr[-1] == '1':
k = len(binStr)-1
while (k > 0) and (binStr[k] in ['.', '1']):
if binStr[k] == '1':
binStr = binStr[:k]+'0'+binStr[k+1:]
k -= 1
if len(binStr)-1-k > places:
binStr = binStr[:k]+'1'+binStr[k+1:-1]
else:
binStr = binStr[:k]+'1'+binStr[k+1:]
return(binStr[:-1])
Test the code:
def do_for(x, p):
bx = float_bin(x, places = p)
Dx = bin_float(bx)
rel = 100*abs(1-Dx/x)
if rel >= 1:
print('n value = {:.6e} binary = {} ({} sig. digits)'.format(x, bx, p),
'n saved = {:.6e} Error = {:.2f}%'.format(Dx, rel))
else:
print('n value = {:.6e} binary = {} ({} sig. digits)'.format(x, bx, p),
'n saved = {:.6e} Error = {:.1e}%'.format(Dx, rel))
do_for(0.234, 8)
do_for(0.234, 3)
do_for(0.234, 2)
do_for(15/16, 4)
do_for(31/32, 4)
do_for(1.00052123, 12)
do_for(0.00052123, 8)
results:
value = 2.340000e-01 binary = 0.0011110000 (8 sig. digits)
saved = 2.343750e-01 Error = 1.6e-01%
value = 2.340000e-01 binary = 0.00111 (3 sig. digits)
saved = 2.187500e-01 Error = 6.52%
value = 2.340000e-01 binary = 0.010 (2 sig. digits)
saved = 2.500000e-01 Error = 6.84%
value = 9.375000e-01 binary = 0.1111 (4 sig. digits)
saved = 9.375000e-01 Error = 0.0e+00%
value = 9.687500e-01 binary = 1.000 (4 sig. digits)
saved = 1.000000e+00 Error = 3.23%
value = 1.000521e+00 binary = 1.00000000001 (12 sig. digits)
saved = 1.000488e+00 Error = 3.3e-03%
value = 5.212300e-04 binary = 0.000000000010001001 (8 sig. digits)
saved = 5.226135e-04 Error = 2.7e-01%