每个人都知道,或者至少,every programmers should know,使用float
类型可能会导致精度错误。然而,在某些情况下,精确的解是很好的,并且在有些情况下,仅仅使用epsilon值进行比较是不够的。不管怎样,这不是重点。
我知道Python中的Decimal
类型,但从未尝试过使用它。它指出"Decimal numbers can be represented exactly"并且我认为它意味着一个允许表示任何实数的聪明实现。我的第一次尝试是:
>>> from decimal import Decimal
>>> d = Decimal(1) / Decimal(3)
>>> d3 = d * Decimal(3)
>>> d3 < Decimal(1)
True
很失望,我回到文件,继续读:
The context for arithmetic is an environment specifying precision [...]
好吧,实际上有一个精度。经典的版本可以复制:
>>> dd = d * 10**20
>>> dd
Decimal('33333333333333333333.33333333')
>>> for i in range(10000):
... dd += 1 / Decimal(10**10)
>>> dd
Decimal('33333333333333333333.33333333')
所以,我的问题是:有没有办法使十进制类型具有无限精度?如果不是,那么比较两个十进制数的更优雅的方法是什么(例如,如果delta小于精度,d3<;1应该返回False)。
目前,当我只做除法和乘法时,我使用Fraction
类型:
>>> from fractions import Fraction
>>> f = Fraction(1) / Fraction(3)
>>> f
Fraction(1, 3)
>>> f * 3 < 1
False
>>> f * 3 == 1
True
这是最好的方法吗?还有其他的选择吗?
不,因为存储一个无理数需要无限的内存。
其中
Decimal
很有用,它表示的是货币数量之类的东西,其中的值需要精确,精度是先验的。从这个问题来看,并不完全清楚
Decimal
比float
更适合您的用例。小数类最适合于金融类型的加法、减法乘法、除法类型的问题:
分数模块与您描述的有理数问题域配合得很好:
对于用于科学工作的纯多精度浮点,请考虑mpmath。
如果您的问题可以保留在符号领域,请考虑sympy。以下是您将如何处理1/3问题:
Sympy对任意精度浮点使用mpmath,包括以符号方式处理有理数和无理数的能力。
考虑√2的无理值的纯浮点表示:
与sympy相比:
您还可以减少值:
但是,如果不小心,您可以看到与直接浮点类似的Sympy问题:
最好用十进制:
或者使用分数或Sympy并将诸如
1.1
之类的值作为比率:或者用理性来表达同情:
你可以玩sympy live。
否;对于实数行上的任何非空间隔,您不能使用有限位以无限精度表示集合中的所有数字。这就是为什么
Fraction
是有用的,因为它将分子和分母存储为整数,而整数可以精确地表示为:相关问题 更多 >
编程相关推荐