VBB*_*VBB 2 python arrays floating-point numpy
我有一个相当简单的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)
Run Code Online (Sandbox Code Playgroud)
嗯,我想......浮点怪物再次袭来.我开始值很大,但不是说大,它搞砸了64位浮点.在我预感,我尝试以下,我认为应该是同样的事情:
nbins = tmin + np.arange(0, tmax-tmin, 0.001)
plt.plot(nbins[::1000] % 1)
Run Code Online (Sandbox Code Playgroud)
田田!那里有一个差异.差异单调地在阵列中的~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
Run Code Online (Sandbox Code Playgroud)
打电话给numpy大师 - 为什么会这样?
你基本上是正确的; 如果您关心数组元素的精确小数,请使用第二种方法.
在您的第一次尝试中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对每个元素的最后添加将具有较差的准确性,这意味着最终,每个元素将经历一次操作,准确性较差.将其与第一次尝试进行比较,其中给定元素的值具有所有先前元素的累积误差.也就是说,元素位于数组中的位置越远,它就越差(如图所示).