Python中的数值精度损失

Python中的数值精度损失,python,floating-accuracy,numerical,Python,Floating Accuracy,Numerical,我想计算一系列数字的标准误差。假设数字是x[i]其中i=1。。。做这件事 我设定 averageX = 0.0 averageXSquared = 0.0 然后我循环所有的I=1,…N,并对每一个进行计算 averageX += x[i] averageXSquared += x[i]**2 然后除以N averageX = averageXC / N averageXSquared = averageXSquared/N 然后取差值的平方根 stdX = math.sqrt(averag

我想计算一系列数字的标准误差。假设数字是
x[i]
其中i=1。。。做这件事

我设定

averageX = 0.0
averageXSquared = 0.0
然后我循环所有的I=1,…N,并对每一个进行计算

averageX += x[i]
averageXSquared += x[i]**2
然后除以N

averageX = averageXC / N
averageXSquared = averageXSquared/N
然后取差值的平方根

stdX = math.sqrt(averageXSquared - averageX * averageX)
这里的参数肯定总是>=0

但是,如果我将all
x[I]=0.07(例如),那么我会得到一个数学域错误,因为根函数的参数为负。似乎有一些精度的损失

该参数的数量级为10e-15

这看起来并不令人鼓舞。我现在必须检查自己,看看结果是否是负面的,然后再扎根


或者我做错了什么。

这不是python的问题,而是一个精度有限的问题。如果将所有数字设置为相同的值,则标准误差在数学上为0,但对于计算机而言则不是。处理这个问题的正确方法是设置非常小的值这不是python的问题,而是一个具有有限精度的问题。如果将所有数字设置为相同的值,则标准误差在数学上为0,但对于计算机而言则不是。正确的处理方法是设置非常小的值正确的方法当然是永远不要减去大的数字。再通过一次,保证非负性(你需要做一些代数来认识到结果在数学上是相同的):


当然,正确的方法是永远不要减去大的数字。再通过一次,保证非负性(你需要做一些代数来认识到结果在数学上是相同的):


如果
stdX=math.sqrt(averageXSquared-averageX*averageX)
始终为正,您将很幸运。正如您所说,它将非常接近
0
,但由于浮点数学的复杂性,它不会完全为零。您是否考虑过使用我建议查看模块。您可以手动设置所需的精度。@AMacK我认为这在这种情况下没有帮助。您需要无限精度。@标记赎金对于10e-15量级的值,30位精度不够吗?如果
stdX=math.sqrt(averageXSquared-averageX*averageX)
始终为正,您将很幸运。正如您所说,它将非常接近
0
,但由于浮点数学的复杂性,它不会完全为零。您是否考虑过使用我建议查看模块。您可以手动设置所需的精度。@AMacK我认为这在这种情况下没有帮助。您需要无限的精度。@markransem对于10e-15级的值,30位精度不够吗?这是一个很好的技巧。值得一提的是,正确的方法(TIOOWTDI)是使用Numpy(如果你能负担得起的话),这是一个很好的技巧。值得一提的是,正确的方法(TIOWTDI)是使用Numpy(如果你能负担得起的话)。
x = [0.7, 0.7, 0.7]
average = sum(x) / len(x)
sqav = sum(y**2 for y in x) / len(x)
stderr = math.sqrt(max(sqav - average**2, 0))
y = [ v - average for v in x ]
dev = sum(v*v for v in y) / len(x)
stderr = math.sqrt(dev)