处理浮点:尤其是numpy python

时间:2016-04-03 00:22:38

标签: python numpy floating-point precision

我想要的价值观 - 1,1.02,1.04,1.06,1.08等...... 所以在python中使用了numpy:

y = [x for x in numpy.arange(1,2,0.02)]

我得到了值 -

1.0,
1.02,
1.04,
1.0600000000000001,
1.0800000000000001,

我在这里有三个问题:

  1. 我如何准确得到值1,1.02,1.04,1.06,1.08等....

  2. 为什么要修正1.02和1.04的值,而不是1.0600000000000001的值,

  3. 当我们无法在可能遇到数千行代码的程序中信任这些基本操作时,我们的程序有多可靠,我们在那做了很多计算?我们如何应对这种情况?

  4. 有一些非常类似的问题可以解决浮点问题,特别是numpy库 -

    Is floating point math broken?

    Why Are Floating Point Numbers Inaccurate?

    虽然他们解决了为什么会发生这种情况,但我在这里更关心如何在日常编程中处理这种情况,特别是在numpy python中?因此,我提出了这些问题。

1 个答案:

答案 0 :(得分:3)

  • 第一个陷阱:不要混淆准确性和打印政策。

在你的例子中:

In [6]: [x.as_integer_ratio() for x in arange(1,1.1,0.02)]
Out[6]: 
[(1, 1),
 (2296835809958953, 2251799813685248),
 (1170935903116329, 1125899906842624),
 (2386907802506363, 2251799813685248),
 (607985949695017, 562949953421312),
 (2476979795053773, 2251799813685248)]

表明只有1具有精确的浮点表示。

In [7]: ['{:1.18f}'.format(f) for f in arange(1,1.1,.02)]
Out[7]: 
['1.000000000000000000',
 '1.020000000000000018',
 '1.040000000000000036',
 '1.060000000000000053',
 '1.080000000000000071',
 '1.100000000000000089']

显示实习生准确性。

In [8]: arange(1,1.1,.02)
Out[8]: array([ 1.  ,  1.02,  1.04,  1.06,  1.08,  1.1 ])

显示numpy如何处理打印,舍入到最多6位数,丢弃尾随0.

In [9]: [f for f in arange(1,1.1,.02)]
Out[9]: [1.0, 1.02, 1.04, 1.0600000000000001, 1.0800000000000001, 1.1000000000000001]

显示python如何处理打印,舍入到最多16位数,在第一位数后丢弃尾随0。

  • 有些建议如何在日常编程中处理这种情况?

此外,对浮子的每次操作都会降低精度 自然float64精度大约为1e-16,足以满足许多应用。减法是精确损失的最常见来源,如此示例中精确结果为0.

In [5]: [((1+10**(-exp))-1)/10**(-exp)-1 for exp in range(0,24,4)]
Out[5]: 
[0.0,
 -1.1013412404281553e-13,
 -6.07747097092215e-09,
 8.890058234101161e-05,
 -1.0,
 -1.0]