如何设置numpy浮点精度?

36

我刚用两种方法算了同一个数字,但在numpy中出现错误。

[[ 0.910221324013388510820732335560023784637451171875]]
[[-0.9102213240133882887761274105287156999111175537109375]]
这个数字在e^(-15)之前是一样的,但之后就不同了。我该如何处理这个误差?
有没有办法限制浮点数的精度呢?
因为我使用这些数字来计算指数函数,即使是微小的差异也会导致令人沮丧的错误...

你的数组是什么数据类型?输出的数字数量太多了,简直疯狂。 - Mark Dickinson
float64。由于仅打印数字不会显示任何差异,因此我添加了np.set_printoptions(precision=70)。 - user42298
2个回答

30

您是关心结果的实际精度,还是只想从两个计算中获得相同的数字?

如果您只想要相同的数字,可以使用np.around()将结果四舍五入到一定的小数位数。但是,这样做只会降低结果的精度。

如果您真的想更精确地计算结果,可以尝试使用np.longdouble类型作为输入数组,根据您的架构和编译器,可能会给您提供一个80或128位的浮点表示,而不是标准的64位np.double*

您可以使用np.finfo比较近似的小数位数精度:

print np.finfo(np.double).precision
# 15

print np.finfo(np.longdouble).precision
# 18

请注意,并非所有的NumPy函数都支持long double - 有些会将其降级为double。

然而,一些编译器(如Microsoft Visual C++)始终将long double视为与double同义词,在这种情况下,np.longdoublenp.double之间的精度没有区别。


3
如果你链接中的话说“numpy.longdouble是指你的C编译器所称的long double类型”,那么不幸的是,对于一些C编译器来说,它并不比double更精确(例如Visual Studio)。尽管如此,还是要为回答问题点赞。 - Pascal Cuoq
1
我不知道有任何主流平台可以提供128位浮点类型。OS X将np.longdouble报告为numpy.float128,但它是错误的——它仍然是旧的80位x87扩展精度类型,填充了6个零字节。(同样,32位Linux经常将相同的类型报告为numpy.float96。) - Mark Dickinson

11
在正常的numpy使用中,数字是双精度的。这意味着精度将小于16位数字。这里有一个解决了相同问题的主题包含在此处
如果需要增加精度,可以使用符号计算...。库mpmath... 是非常好的一个。优点是可以使用无限精度。然而,计算速度比numpy慢。
以下是一个例子:
# The library mpmath is a good solution
>>> import sympy as smp
>>> import mpmath as mp

>>> mp.mp.dps = 50  # Computation precision is 50 digits
# Notice that the difference between x and y is in the digit before last (47th)
>>> x = smp.mpmath.mpf("0.910221324013388510820732335560023784637451171875")
>>> y = smp.mpmath.mpf("0.910221324013388510820732335560023784637451171865")
>>> x - y  # Must be equal to 1e-47 as the difference is on the 47th digit
mpf('1.000014916280995001003481719184726944958705912691304e-47')

使用numpy您无法做得更好。您可以使用更高的精度计算指数。

>>> smp.exp(x).evalf(20)
2.4848724344693696167
请注意,在SymPy 0.7.6版本之后,mpmath不再与SymPy一起打包,而是成为其依赖项。 这意味着在更新的SymPy版本中,sympy.mpmath函数已经移动到了mpmath
请提供需要翻译的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接