Python浮点数-字符串-浮点数的奇怪问题

11
>>> float(str(0.65000000000000002))

0.65000000000000002

>>> float(str(0.47000000000000003))

0.46999999999999997     ???

这里发生了什么事情?我该如何将0.47000000000000003转换为字符串并将结果值返回到浮点数?

我在Windows上使用Python 2.5.4。


3
RC:我认为很多人(包括程序员)甚至不知道IEEE 754定义了浮点数(并非每个人都会阅读语言规范:-))。因此,除非有关于标准本身的具体问题,否则我认为“浮点数”标签会是更好的选择。 - Joey
5
那些问这类问题的人肯定不知道 IEEE-754 是什么。 - sth
不知道浮点标签,但肯定比规范名称更好。 - user180100
4个回答

16

str(0.47000000000000003) 会返回 '0.47',而 float('0.47') 则可能会得到 0.46999999999999997。这是由于浮点数的表示方式所导致的(请参见wikipedia文章)。

注意:如果需要精度,应使用 Decimal,但 float(repr(0.47000000000000003))eval(repr(0.47000000000000003)) 可以得到预期结果。


注意:这里使用十进制不仅是为了精度,也是为了准确性。 - Joey
我不确定,但我认为“precision”和“exactness”是同义词,其中“precision”是通常使用的术语。 - tzot
1
请参阅http://en.wikipedia.org/wiki/Precision_vs._accuracy - 讨论的数字非常精确,但讨论的问题是它们不准确。 - gravitystorm

3

float(和double)没有无限精度。当你对它们进行操作时,自然会出现舍入误差。


2

这是一个Python FAQ

同样的问题也经常出现在comp.lang.python中。

我认为它是一个FAQ的原因是,因为Python在其他方面都非常完美;-),我们期望它能像我们在学校里学到的那样完美地执行算术运算。然而,任何完成过数值方法课程的人都会告诉您,浮点数离完美还有很长的路要走。

Decimal是一个很好的替代品,如果您想要更快的速度和更多的选项,gmpy也是一个不错的选择。


0

通过这个例子,我认为在Python中进行除法时出现了错误。

    >>> print(int(((48/5.0)-9)*5))
    2

我用简单的方法解决了这个问题

    >>> print(int(round(((48/5.0)-9)*5,2)))
    3

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