我发现了几种将Integer和Float值都转换为二进制值的方法,每种方法都有其问题。我需要在0到10,000之间的整数/浮点输入 ,转换为 16位(完全)二进制字符串,随机操作位,然后转换回到Integer / Float(取决于参数)。
但是,我一直在使用以下代码:
def convert_to_binary(value):
'''
Converts a float to a 16-bit binary string.
'''
[d] = struct.unpack('>Q', struct.pack('>d', value))
return str('{:016b}'.format(d))
def convert_back(bin_num):
'''
Converts binary string to a float.
'''
print type(bin_num)
print bin_num
bf = int_to_bytes(int(bin_num, 2), 8) # 8 bytes needed for IEEE 754 binary64.
print struct.unpack('>d', bf)[0]
return struct.unpack('>d', bf)[0]
# return struct.unpack('d', struct.pack('Q', bin_num))[0]
#bin_num.pack('B*').unpack('g').first
def int_to_bytes(n, minlen=0): # Helper function
'''
Turns integer/long to byte string.
'''
nbits = n.bit_length() + (1 if n < 0 else 0) # +1 for any sign bit.
nbytes = (nbits+7) // 8 # Number of whole bytes.
b = bytearray()
for _ in range(nbytes):
b.append(n & 0xff)
n >>= 8
if minlen and len(b) < minlen: # Zero padding needed?
b.extend([0] * (minlen-len(b)))
return bytearray(reversed(b)) # High bytes first.
结果是这样的(由于我无法从终端复制和粘贴,所以采用图片形式):
我了解二进制文件的类型不同(有符号/无符号,不同的位数等),但是我需要我的输出是 think 的无符号缩写。 。我所有的数字都是正值,并且为了允许以后使用的位操作,它们的长度必须恰好是16位数字->(如果它们是浮点值,则可以使用二进制的多余数字但是只需更改前16位,然后跟随的就是小数点后面的内容,对吧?)
首先,我应该同时为Float输入和Integer输入编写函数吗?
第二,如何更改代码以实现所需的输出,而无需简单地使用pop
等将二进制文件的长度减少到16?
答案 0 :(得分:1)
我可以看到,这不是一个很受欢迎的问题,所以我将在此同时提出:
def convert_to_binary(value):
'''
Converts a float to a 16-bit binary string.
'''
n = ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0']
value = int(value)
if value > 2**15:
if value > 2**16:
print "Value too large"
else:
n[0] = '1'
value = value - (2**15)
if value > 2**14:
n[1] = '1'
value = value - (2**14)
if value > 2**13:
n[2] = '1'
value = value - (2**13)
if value > 2**12:
n[3] = '1'
value = value - (2**12)
if value > 2**11:
n[4] = '1'
value = value - (2**11)
if value > 2**10:
n[5] = '1'
value = value - (2**10)
if value > 2**9:
n[6] = '1'
value = value - (2**9)
if value > 2**8:
n[7] = '1'
value = value - (2**8)
if value > 2**7:
n[8] = '1'
value = value - (2**7)
if value > 2**6:
n[9] = '1'
value = value - (2**6)
if value > 2**5:
n[10] = '1'
value = value - (2**5)
if value > 2**4:
n[11] = '1'
value = value - (2**4)
if value > 2**3:
n[12] = '1'
value = value - (2**3)
if value > 2**2:
n[13] = '1'
value = value - (2**2)
if value > 2**1:
n[14] = '1'
value = value - (2**1)
if value >= 2**0:
n[15] = '1'
value = value - (2**0)
n = ''.join(n)
n = str(n)
print str(n)
return str(n)
def convert_back(bin_num):
"""
Converts binary string to a float.
"""
value = 0
print type(bin_num)
n = list(bin_num)
if n[0] == '1':
value = value + (2 ** 15)
if n[1] == '1':
value = value + (2 ** 14)
if n[2] == '1':
value = value + (2 ** 13)
if n[3] == '1':
value = value + (2 ** 12)
if n[4] == '1':
value = value + (2 ** 11)
if n[5] == '1':
value = value + (2 ** 10)
if n[6] == '1':
value = value + (2 ** 9)
if n[7] == '1':
value = value + (2 ** 8)
if n[8] == '1':
value = value + (2 ** 7)
if n[9] == '1':
value = value + (2 ** 6)
if n[10] == '1':
value = value + (2 ** 5)
if n[11] == '1':
value = value + (2 ** 4)
if n[12] == '1':
value = value + (2 ** 3)
if n[13] == '1':
value = value + (2 ** 2)
if n[14] == '1':
value = value + (2 ** 1)
if n[15] == '1':
value = value + (2 ** 0)
print value
return value
答案 1 :(得分:1)
我遇到了同样的问题,所以我投票赞成你的问题和答案,但是我找到了一个更简单,更短的解决方案。
这是一个例子:
In [1]: val = 15
In [2]: bin_ = '{0:016b}'.format(val)
In [3]: bin_
Out[3]: '0000000000001111'
或者:
In [4]: bin_ = bin(val)[2:].zfill(16)
In [5]: bin_
Out[5]: '0000000000001111'
In [6]: int(bin_, 2)
Out[6]: 15
[注意]:
这将在 Python 2.7 和 Python 3.x
上运行