numpy float的"resolution"参数究竟是什么?

Ser*_*giy 5 python floating-point precision numpy floating-accuracy

我正在寻求更多了解numpy浮点数的"resolution"参数(我猜任何计算机定义的浮点数).

请考虑以下脚本:

import numpy as np
a = np.finfo(10.1)
print a
Run Code Online (Sandbox Code Playgroud)

我得到一个输出,其中打印出来:

precision=15   resolution= 1.0000000000000001e-15
max= 1.797(...)e+308
min= -max
Run Code Online (Sandbox Code Playgroud)

numpy文档指定:"resolution :(适当类型的浮点数)此类型的近似小数分辨率,即10** - 精度." 资源

分辨率是从精度得出的,但不幸的是,这个定义有点圆形"precision(int):这种浮点精确的小数位数." 资源

我知道浮点数只是实数的有限表示,因此它们的表示有误差,而精度可能是这种偏差的量度.但实际上,如果我使用小于分辨率的数字执行操作,是否意味着我应该期望结果是错误的?如果给出精度,我怎样才能量化两个浮点数的误差?如果分辨率与1e-15一样"大",为什么最小允许数量大约为1e-308?

先感谢您!

Joe*_*ton 12

简短的回答是" 不要"混淆numpy.finfo使用numpy.spacing ".

finfo在对价值dtype进行spacing操作的同时进行操作.

背景资料

首先,一些一般性解释:


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

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

但是,np.finfo如果数字是用基数为10的科学记数法写的,那么"精确度"(如所指的那样)基本上是有效位数.如果值以相同的基数10科学记数法(即10^-precision)写成,则"分辨率"是系数的分辨率(前面的部分).换句话说,两者都只是系数的函数.

NumPy的特异

因为numpy.finfo,"精确度"和"分辨率"只是彼此相反. 两个人都没有告诉你特定数字的表达有多紧密.它们纯粹是一种功能dtype.

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

例子

举个例子:

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
Run Code Online (Sandbox Code Playgroud)

但精度和分辨率不会改变:

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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

具体问题

现在回答您的具体问题:

但实际上,如果我使用小于分辨率的数字执行操作,是否意味着我应该期望结果是错误的?

不,因为精度/分辨率(以numpy.finfo术语表示)仅是系数的函数,并未考虑指数.非常小且非常大的数字具有相同的"精度",但这不是绝对的"错误".

根据经验,当使用"分辨率"或"精确"术语时finfo,请考虑科学记数法.如果我们在相似数量的小数字上运行,我们不需要担心太多.

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

1.20000 x 10^-19 + 2.50000 x 10^-20 => 1.45000 x 10^19
Run Code Online (Sandbox Code Playgroud)

但是,如果我们对幅度大不相同但精度有限的数字(再次,6位有效数字)进行操作:

1.20000 x 10^6 + 2.50000 x 10^-5 => 1.20000
Run Code Online (Sandbox Code Playgroud)

我们将开始清楚地看到效果.

如果给出精度,我怎样才能量化两个浮点数的误差?

使用np.spacing(result).

如果分辨率与1e-15一样"大",为什么最小允许数量大约为1e-308?

同样,在这种情况下,"分辨率"没有考虑指数,只考虑前面的部分.


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