【问题标题】:Avoiding small numerical errors when using IPython使用 IPython 时避免小的数值错误
【发布时间】:2015-12-28 00:38:34
【问题描述】:

我一直在从 Matlab 切换到 IPython。 在 IPython 中,如果我们将 3.1 乘以 2.1,结果如下:

In [297]:

3.1 * 2.1
Out[297]:
6.510000000000001

有一个小的舍入误差。这不是一个大问题,但它有点烦人。我假设它是在将十进制数转换为二进制数时出现的,反之亦然,对吗?

但是,在 Numpy 数组中,结果是正确的:

>>> np.array([3.1 * 2.1])
array([ 6.51])

在Matlab命令行提示下,结果也是正确的:

>> 3.1 * 2.1

ans =

    6.5100

上述 Python 中的舍入错误看起来很烦人。在 python 交互模式或 IPython 中是否有一些方法可以避免此错误?

【问题讨论】:

  • 一般来说,如果你需要浮点精度,你应该只使用库,但你可以取出小数点,做乘法,然后将小数点插入到你的输出中。对于您的示例,您将执行 31*21=651,并且由于您将两个数字都乘以 10,并且 10*10 是 100,因此它变为 6.51
  • 这不是一个四舍五入的错误。 ipython 显示的小数点比其他两个打印件多。
  • @hpaulj 我称它为舍入错误,因为 3.1 * 2.1 在正常数学中确实等于 6.51。从某种意义上说,你是对的,numpy 和 Python 浮点数之间的外观差异没有意义,尽管两者都受到这种不精确的影响。

标签: python numpy floating-point ipython


【解决方案1】:

numpy 的结果并不比纯 Python 的结果更精确 - 浮点不精度只是对你隐藏,因为默认情况下,numpy 打印的结果的小数位更少:

In [1]: float(np.array([3.1 * 2.1]))
Out[1]: 6.510000000000001

您可以使用np.set_printoptions 控制 numpy 如何显示浮点数。例如,要打印 16 位小数而不是通常的 8 位:

In [2]: np.set_printoptions(precision=16)

In [3]: np.array([3.1 * 2.1])
Out[3]: array([ 6.5100000000000007])

在 IPython 中,您还可以使用 %precision 魔法来控制漂亮打印普通 Python 浮点数时显示的小数位数:

In [4]: %precision 8
Out[4]: u'%.8f'

In [5]: 3.1 * 2.1
Out[5]: 6.51000000

请注意,这纯粹是装饰性的 - 3.1 * 2.1 的值仍将等于 6.5100000000000006750155990... 而不是 6.51

【讨论】:

    【解决方案2】:

    在 Octave 中,一个 MATLAB 克隆,我可以显示那些遥远的小数:

    octave:12> printf("%24.20f\n", 3.1*2.1)
         6.51000000000000067502
    

    他们也出现在你的numpy.array

    In [6]: np.array([3.1*2.1]).item()
    Out[6]: 6.510000000000001
    

    甚至组件术语也涉及这种舍入:

    octave:13> printf("%24.20f\n", 3.1)
      3.10000000000000008882
    octave:14> printf("%24.20f\n", 2.1)
      2.10000000000000008882
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      相关资源
      最近更新 更多