Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将二进制(字符串)转换为浮点值?_Python_Python 3.x - Fatal编程技术网

Python 如何将二进制(字符串)转换为浮点值?

Python 如何将二进制(字符串)转换为浮点值?,python,python-3.x,Python,Python 3.x,我想把二进制数转换成浮点数。下面是一个可能性的例子: >>> float(-0b1110) 提供正确的输出: -14.0 不幸的是,我使用的是二进制字符串,也就是说,我需要类似于float('-0b1110') 但是,这不起作用: 浮动('-0b1110') 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 ValueError:浮点()的文本无效:-0b1110 我尝试使用binascii.a2b_qp(string[,header])将引用的可打印数据块转换回二进

我想把二进制数转换成浮点数。下面是一个可能性的例子:

>>> float(-0b1110)
提供正确的输出:

-14.0
不幸的是,我使用的是二进制字符串,也就是说,我需要类似于
float('-0b1110')

但是,这不起作用:

浮动('-0b1110') 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 ValueError:浮点()的文本无效:-0b1110 我尝试使用
binascii.a2b_qp(string[,header])
将引用的可打印数据块转换回二进制并返回二进制数据。但最终,我得到了同样的错误:

浮动(binascii.a2b_qp('-0b1110')) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 ValueError:浮点()的文本无效:-0b1110 我理解输出数字是整数的情况,但是如果我想得到数字12.546呢?那么二进制字符串的函数调用是什么样子的呢

float(int('-0b1110',0))
这对我很有用

如果您有一个表示浮点数而不是整数的64位字符串,则可以执行三步转换-第一步将字符串转换为整数,第二步将其转换为8字节字符串,第三步将这些位重新解释为浮点

>>> import struct
>>> s = '0b0100000000101001000101111000110101001111110111110011101101100100'
>>> q = int(s, 0)
>>> b8 = struct.pack('Q', q)
>>> struct.unpack('d', b8)[0]
12.546
当然,您可以将所有这些步骤组合成一行

>>> s2 = '0b1100000000101100000000000000000000000000000000000000000000000000'
>>> struct.unpack('d', struct.pack('Q', int(s2, 0)))[0]
-14.0
您可以使用eval(“”),然后根据需要将其转换为float。例如:

>> eval('-0b1110')
-14
>> float(eval('-0b1110'))
-14.0

通过在内置函数中将基数设置为2,可以将字符串形式的二进制数转换为整数,但是需要先去掉
0b
。然后,您可以将结果传递到
float()
以获得最终结果:

>>> s = '-0b1110'
>>> float(int(s.replace('0b', ''), 2))
-14.0
edit:显然,只有在Python 2.5及以下版本上才需要去掉
0b
,Mark的回答在Python 2.6上效果很好,但我在Python 2.5上看到的是:

>>> int('-0b1110', 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 2: '-0b1110'
>>int('-0b1110',2)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
ValueError:基为2的int()的文本无效:'-0b1110'

另一个选择是

from ast import literal_eval

float_str = "-0b101010101"
result = float(literal_eval(float_str))

与内置的“eval”不同,literal_eval即使在用户输入上也可以安全运行,因为它只能解析Python文本,不会执行表达式,这意味着它也不会调用函数。

在您的一条评论中,您指出二进制数表示8字节长的IEEE 754 binary64格式的浮点数。但是,这与作为示例显示的
-0b1110
值不一致,因此我忽略了它,并使用我自己的格式正确的输入数据作为示例,以测试下面显示的答案

基本上,首先将二进制字符串转换为整数值,然后再转换为原始字节字符串,然后将原始字节字符串传递给
struct.unpack()
,以便最终转换为浮点值。下面显示的
bin\u to\u float()
函数驱动该过程。尽管没有说明,二进制输入字符串参数的前缀可以是
'0b'

from codecs import decode
import struct


def bin_to_float(b):
    """ Convert binary string to a float. """
    bf = int_to_bytes(int(b, 2), 8)  # 8 bytes needed for IEEE 754 binary64.
    return struct.unpack('>d', bf)[0]


def int_to_bytes(n, length):  # Helper function
    """ Int/long to byte string.

        Python 3.2+ has a built-in int.to_bytes() method that could be used
        instead, but the following works in earlier versions including 2.x.
    """
    return decode('%%0%dx' % (length << 1) % n, 'hex')[-length:]


def float_to_bin(value):  # For testing.
    """ Convert float to 64-bit binary string. """
    [d] = struct.unpack(">Q", struct.pack(">d", value))
    return '{:064b}'.format(d)


if __name__ == '__main__':

    for f in 0.0, 1.0, -14.0, 12.546, 3.141593:
        print('Test value: %f' % f)
        binary = float_to_bin(f)
        print(' float_to_bin: %r' % binary)
        floating_point = bin_to_float(binary)  # Round trip.
        print(' bin_to_float: %f\n' % floating_point)
这对我有用。 使用Python3.4测试:

def float_to_bin(num):
    return bin(struct.unpack('!I', struct.pack('!f', num))[0])[2:].zfill(32)

def bin_to_float(binary):
    return struct.unpack('!f',struct.pack('!I', int(binary, 2)))[0]

float_to_bin(bin_to_float(float_to_bin(123.123))) == float_to_bin(123.123)
>>> True

很好,但请看我答案中的ast.literal\u eval-这是一个有趣的技巧。根据维基百科0 10000000 1001001000001111111011,这是圆周率的值,精确到24位。>>>浮点数(整数('0B01000000000001001000011111011',0')1078530011。0@wim否则,如果in只能得到整数部分,那么转换为float又有什么意义呢?但是Python无论如何都不支持二进制浮点,所以这些解决方案(包括
ast.literal\u eval
)都不起作用。@nvm,这个问题以整数二进制常量为例。这与浮点二进制的要求完全不符,因为-14.0的表示形式不是-0b1110。@MarkRansom是问题的最后一部分,我引用“我理解输出数字是整数的情况,但是如果我想得到数字12.546呢?那么函数调用二进制字符串应该是什么样子?”
12.546
的二进制表示形式是什么样的——是IEEE 754二进制32还是二进制64?如果不是,二进制点是如何表示的,或者它在字符串中的假定位置在哪里?浮点12.546的二进制表示是IEEE 754 binary64.OK,但
'0b10110011000000'
-14.0
的IEEE 754 binary64表示,而不是“-0b1110”。实际上,
-14.0
的IEEE 754二进制64表示法是
'110000000000000000000000000000000000000000000000000000'
(在我之前的评论中,显示的数字是little endian解释,但提出的观点保持不变)。这很好。正是我想要的,谢谢!你不应该去掉前缀“0b”,你应该通过传递基数0来使用它。我使用了这个代码和“0B001111100000000000000000000000000000”,它应该是1.0 IEEE-754,但我得到了1065353216.0?我糟糕的文字评估想要小端表示而不是大端表示?