使用 IPython 时避免小的数值错误
Avoiding small numerical errors when using IPython
我一直在从 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 中是否有一些方法可以避免此错误?
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
。
在 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
我一直在从 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 中是否有一些方法可以避免此错误?
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
。
在 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