如何在Python中将表示二进制小数的字符串转换为数字

8

假设我们有一个表示二进制小数的字符串,例如:

".1"

作为一个十进制数,这个数是0.5。Python中是否有标准的方法将这样的字符串转换为数字类型(无论是二进制还是十进制都不是严格重要)。
对于整数,解决方案很简单:
int("101", 2)
>>>5

int()函数可以接受一个可选的第二个参数来提供进制,但是float()函数不行。

我正在寻找与此功能等效(我想)的内容:

def frac_bin_str_to_float(num):
    """Assuming num to be a string representing
    the fractional part of a binary number with
    no integer part, return num as a float."""
    result = 0
    ex = 2.0
    for c in num:
        if c == '1':
            result += 1/ex 
        ex *= 2
    return result

我认为这可以满足我的需求,尽管可能会有一些特殊情况我没有考虑到。

在Python中是否有内置或标准方法可以实现这个功能?


好奇一下,你需要这个做什么? - Mark Dickinson
4个回答

8
以下是表达相同算法的一种简洁方式:
def parse_bin(s):
    return int(s[1:], 2) / 2.**(len(s) - 1)

它假设字符串以点开始。如果您想要更通用的内容,以下内容将处理整数和小数部分:

def parse_bin(s):
    t = s.split('.')
    return int(t[0], 2) + int(t[1], 2) / 2.**len(t[1])

例如:

In [56]: parse_bin('10.11')
Out[56]: 2.75

1
确实,这样更加简洁;谢谢NPE。不过我想确认一下,这是否证实了我的猜测,即Python(或标准/流行模块)中没有内置的东西可以处理这种转换?如果可以的话,我希望不必重复造轮子。谢谢! - Tom Scrace
2
@TomScrace:是的,你说得对,这方面没有内置功能。对于十六进制,有类似的float.fromhex形式。但这并不是一个非常普遍的需求。 - Mark Dickinson

4
合理的做法是抑制小数点而非在其上进行分割,代码如下。这个bin2float函数(与之前回答中的parse_bin函数不同)正确处理没有小数点的输入(在这种情况下只返回整数而非浮点数)。
例如,调用 bin2float('101101'), bin2float('.11101'), 和 bin2float('101101.11101') 分别返回 45, 0.90625, 45.90625。
def bin2float (b):
    s, f = b.find('.')+1, int(b.replace('.',''), 2)
    return f/2.**(len(b)-s) if s else f

3

如果您将硬编码的“2”替换为该进制,实际上可以将James的代码推广到从任何数字系统转换。

def str2float(s, base=10):
    dot, f = s.find('.') + 1, int(s.replace('.', ''), base)
    return f / float(base)**(len(s) - dot) if dot else f

0
您可以使用 二进制小数 包。使用此包,您可以将二进制小数字符串转换为浮点数,反之亦然。
示例:
>>> from binary_fractions import Binary
>>> float(Binary("0.1"))
0.5
>>> str(Binary(0.5))
'0b0.1'

它有许多更多的辅助函数来操作二进制字符串,例如:移位、加法、填充、转换为指数形式、反转等...

PS:不要介意我自己吹嘘,我是这个包的作者。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接