确定浮点数的多少个十进制数字是精确的



以下错误发生在小数点后第14位:

>>> 1001*.2
200.20000000000002

这里*错误发生在第18位小数上:

>>> from decimal import Decimal
>>> Decimal.from_float(.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
#                           ^ 
#                           |_ here 

*注意:我使用Fraction,因为>>> 0.1在控制台中显示为0.1,但我认为这与它的打印方式有关,而不是它的存储方式。

:

  • 是否有办法确定错误将发生在哪个精确的十进制数字上?
  • Python 2和Python 3有区别吗?

如果我们假设小部件的大小是精确存储的,那么有两个错误来源:size_hint从十进制到二进制的转换,以及乘法。在Python中,它们都应该被正确地四舍五入到最接近的位置,所以每个都应该有半个ulp(最后一个单位)的相对误差。由于第二个操作是乘法运算,我们可以将边界相加得到总的相对误差,其边界为1 up,或2-53

转换为十进制:

>>> math.trunc(math.log10(2.0**-53))
-15

这意味着你应该精确到15个有效数字。

Python 2和3之间应该没有任何区别:Python长期以来对浮点行为相当严格,我所知道的唯一变化是round函数的行为,这里没有使用

回答问题的小数到双精度浮点数转换部分…

在0.0和0.1之间的十进制分数的转换将适用于15-16位十进制数字(注意:从该点后的第一个非零数字开始计数)

0.1 = 0.1000000000000000055511151231257827021181583404541015625适合16位数字(四舍五入到17是0.10000000000000001;四舍五入到16是0.1)。

0.2 = 0.200000000000000011102230246251565404236316680908203125也适用于16位。

(一个只适用于15位数字的例子:

0.81 = 0.810000000000000053290705182007513940334320068359375

我建议你读一读pep485

使用==运算符比较浮点值不是正确的方法,而是考虑使用数学。Isclose或cmath。Isclose,这里有一个使用你的值的小例子:

try:
    from math import isclose
    v1 = 101 * 1 / 5
    v2 = 101 * (1 / 5)
except:
    v1 = float(101) * float(1) / float(5)
    v2 = float(101) * (float(1) / float(5))
    def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
        return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
print("v1==v2 {0}".format(v1 == v2))
print("isclose(v1,v2) {0}".format(isclose(v1, v2)))

正如你所看到的,我在python 2中显式地强制转换为float。并使用文档中提供的函数,使用python。x我只是直接使用你的值和数学模块提供的函数。

相关内容

  • 没有找到相关文章

最新更新