numpy float 的 "resolution" 参数到底是什么

What exactly is the "resolution" parameter of numpy float

我正在寻求对 numpy 浮点数的 "resolution" 参数的更多理解(我想任何计算机都为此定义了浮点数)。

考虑以下脚本:

import numpy as np
a = np.finfo(10.1)
print a

我得到一个输出,其中打印出其他内容:

precision=15   resolution= 1.0000000000000001e-15
max= 1.797(...)e+308
min= -max

numpy 文档指定:"resolution: (floating point number of the appropriate type) The approximate decimal resolution of this type, i.e., 10**-precision." source

分辨率源自精度,但不幸的是这个定义有点循环"precision (int): The approximate number of decimal digits to which this kind of float is precise." source

我知道浮点数只是实数的有限表示,因此它们的表示存在误差,精度可能是这种偏差的衡量标准。但实际上,这是否意味着如果我使用小于分辨率的数字执行操作,我应该期望结果是错误的?给定精度,我如何量化两个浮点数的误差,例如加法?如果分辨率为"large" as 1e-15,为什么最小的允许数字在1e-308的数量级?

提前致谢!

简短的回答是“不要混淆numpy.finfo with numpy.spacing”。

finfodtype 进行运算,而 spacing 对值进行运算。

背景信息

不过,首先,一些一般性的解释:


要理解的关键部分是浮点数类似于科学记数法。就像你将 0.000001 写成 1.0 x 10^-6 一样,浮点数类似于 c x 2^q。换句话说,它们有两个独立的部分 - 系数 (c, a.k.a. "significand") 和指数 (q)。这两个值存储为整数。

因此,一个值的表示程度(让我们将其视为离散化程度)是两个部分的函数,取决于值的大小 .

然而,"precision"(如 np.finfo 所指)本质上是有效数字的位数,如果数字是以 10 进制的科学记数法书写的话。 "resolution" 是系数(前面的部分)的分辨率,如果该值以相同的 10 进制科学计数法(即 10^-precision)写入。换句话说,两者都只是系数的函数。

特定于 Numpy

对于numpy.finfo,"precision"和"resolution"只是彼此的倒数。 没有人告诉您某个特定数字的表示有多接近。它们纯粹是 dtype.

的函数

相反,如果您担心离散化的绝对程度,请使用 numpy.spacing(your_float)。这将 return 该特定格式下一个最大值的差异(例如,float32float64 不同)。

例子

举个例子:

In [1]: import numpy as np

In [2]: np.spacing(10.1)
Out[2]: 1.7763568394002505e-15

In [3]: np.spacing(10000000000.1)
Out[3]: 1.9073486328125e-06

In [4]: np.spacing(1000000000000.1)
Out[4]: 0.0001220703125

In [5]: np.spacing(100000000000000.1)
Out[5]: 0.015625

In [6]: np.spacing(10000000000000000.1)
Out[6]: 2.0

但精度和分辨率没有改变:

In [7]: np.finfo(10.1).precision
Out[7]: 15

In [8]: np.finfo(10000000000000000.1).precision
Out[8]: 15

In [9]: np.finfo(10.1).resolution
Out[9]: 1.0000000000000001e-15

In [10]: np.finfo(10000000000000000000.1).resolution
Out[10]: 1.0000000000000001e-15

另请注意,所有这些都取决于您使用的数据类型:

In [11]: np.spacing(np.float32(10.1))
Out[11]: 9.5367432e-07

In [12]: np.spacing(np.float32(10000000000000.1))
Out[12]: 1048576.0

In [13]: np.finfo(np.float32).precision
Out[13]: 6

In [14]: np.finfo(np.float32).resolution
Out[14]: 1e-06

In [15]: np.spacing(np.float128(10.1))
Out[15]: 8.6736173798840354721e-19

In [16]: np.spacing(np.float128(10000000000000.1))
Out[16]: 9.5367431640625e-07

In [17]: np.finfo(np.float128).precision
Out[17]: 18

In [18]: np.finfo(np.float128).resolution
Out[18]: 1.0000000000000000007e-18

具体问题

现在回答您的具体问题:

But practically, does it mean that I should expect results to be erroneous if I preform operations using numbers less than the resolution?

不,因为 precision/resolution(在 numpy.finfo 术语中)只是系数的函数,并没有考虑指数。非常小和非常大的数字具有相同的 "precision",但这不是绝对的 "error"。

根据经验,在使用 finfo 中的 "resolution" 或 "precision" 术语时,请考虑科学记数法。如果我们对具有相似幅度的小数字进行操作,我们不需要担心太多。

让我们采用具有 6 位有效数字的十进制数学案例(有点类似于 float32):

1.20000 x 10^-19 + 2.50000 x 10^-20 => 1.45000 x 10^19

但是,如果我们对数量级差异很大但精度有限(同样是 6 位有效数字)的数字进行运算:

1.20000 x 10^6 + 2.50000 x 10^-5 => 1.20000

我们将开始非常清楚地看到效果。

How can I quantify the error, for say addition, of two floating point numbers given their precision?

使用np.spacing(result).

If the resolution is as "large" as 1e-15, why would the smallest allowable number be on the order of 1e-308?

同样,本例中的 "resolution" 不考虑指数,只考虑前面的部分。


希望这有助于澄清一些事情。所有这一切都让人有些困惑,每个人都会在某个时候被它咬伤。尝试建立一些关于它的直觉并知道要调用哪些函数以在您选择的平台中准确找出答案是很好的!