Numpy arange浮点不一致

时间:2016-10-20 11:20:39

标签: python arrays numpy floating-point

我有一个相当简单的numpy任务:创建一个长数组,每个元素增加0.001。当然,np.arange就是答案。我将自己限制为默认精度(float64)。对结果的简单检查是数组的每1000个元素应该具有相同的小数部分。我通过绘图检查(见附图中的蓝线),但事实并非如此。

tmin = 212990552.75436273
tmax = 213001474.74473435
tbins = np.arange(tmin, tmax, 0.001)
plt.plot(tbins[::1000] % 1)
嗯,我想......浮点怪物再次袭来。我的起始值很大,但 大,它搞砸了64位浮点数。在我预感的时候,我尝试以下内容,我认为应该是同样的事情:

nbins = tmin + np.arange(0, tmax-tmin, 0.001)
plt.plot(nbins[::1000] % 1)

多田!那里存在差异。差异单调地在阵列中的~10 ^ 7个元素上爬升到0.14。请注意,由于tmin是x.xxx36273,我希望所有数字都是x.xxx36273。 nbins有,tbins没有。

In [68]: tbins[-1]
Out[68]: 213001474.60374644

In [69]: nbins[-1]
Out[69]: 213001474.74436274

在那里打电话给numpy大师 - 为什么会这样?

Drift seen in the decimal part - blue line is tbins, green line is nbins

2 个答案:

答案 0 :(得分:5)

你基本上是正确的;如果你关心数组元素的精确小数,请使用第二种方法。

在您第一次尝试tbins = np.arange(tmin, tmax, 0.001)时,您将在一次计算中混合大小浮点数。给定元素的确切值计算为前一个元素和0.001的总和。与0.001相比,此前一个值总是很大,因此这个求和将不会非常准确(为了获得浮点加法时的最佳精度,两个操作数应该具有相同的数量级)。

在您的第二次尝试nbins = tmin + np.arange(0, tmax-tmin, 0.001)中,np.arange(0, tmax-tmin, 0.001)部分中的摘要都非常准确,因为遗漏了大量tmin,并且最后只添加了tmin。最后一个$wmi = Get-WMIObject -Class Win32_DCOMApplicationSetting -Filter "AppID='{00020906-0000-0000-C000-000000000046}'" -EnableAllPrivileges $wmi.AuthenticationLevel = 2 $wmi.put() 添加到每个元素将具有较差的准确性,这意味着最终,每个元素将经历一个操作,准确性较差。将其与第一次尝试进行比较,其中给定元素的值具有所有先前元素的累积误差。也就是说,数组中的元素位置越远,它就越差(如图所示)。

答案 1 :(得分:2)

  

数组的每1000个元素应该具有相同的小数部分

对于实际数字而言,这是正确的,但对于浮点值则不然。您获得的浮点值并不总是与您期望的实际数字相匹配。例如,您希望tbins[1]为数字212990552.75536273,但您会得到212990552.75536272,这是最接近的float64值:

In [58]: tbins[0]
Out[58]: 212990552.75436273

In [59]: tbins[1]
Out[59]: 212990552.75536272

In [60]: tbins[0] + 0.001
Out[60]: 212990552.75536272

In [61]: 212990552.75536273
Out[61]: 212990552.75536272