c# – 浮点加法:精度损失问题

前端之家收集整理的这篇文章主要介绍了c# – 浮点加法:精度损失问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
简而言之,我如何执行一个b,使得由于截断而导致的任何精度损失远离零而不是零?

漫长的故事

为了计算集合的样本均值和方差,我计算一系列长的浮点值的总和.由于Var(X)= E(X2)-E(X)2,足以保持所有数字的运行计数,到目前为止所有数字的总和以及所有数字的平方和.

到现在为止还挺好.

然而,绝对需要E(X2)> E(X)2,由于浮点精度并不总是这样.在伪代码中,问题是这样的:

int count;
double sum,sumOfSquares;
...
double value = <current-value>;
double sqrVal = value*value; 

count++;
sum += value; //slightly rounded down since value is truncated to fit into sum
sumOfSquares += sqrVal; //rounded down MORE since the order-of-magnitude 
//difference between sqrVal and sumOfSquares is twice that between value and sum;

对于可变序列,这不是一个大问题 – 您最终稍微低估方差,但这往往不是一个大问题.然而,对于具有非零均值的恒定或几乎恒定的集合,可以意味着E(X2) E(X)2,导致负的计算方差,这违反了消费代码的期望.

现在,我知道了Kahan Summation,这不是一个有吸引力的解决方案.首先,它使代码易于优化变幻莫测(取决于优化标志,代码可能或可能不会出现这个问题),其次,问题并不是真正由于精度 – 这是足够好的 – 这是因为添加引入了系统误差为零.如果我可以执行该行

sumOfSquares += sqrVal;

以确保sqrVal四舍五入,而不是下降到sumOfSquares的精度,我会有一个数字合理的解决方案.但是如何才能实现呢?

编辑:完成的问题 – 为什么要在标签字段的下拉列表中输入提交问题?

解决方法

还有一个单程算法重新排列计算.在
代码
n = 0
mean = 0
M2 = 0

for x in data:
    n = n + 1
    delta = x - mean
    mean = mean + delta/n
    M2 = M2 + delta*(x - mean)  # This expression uses the new value of mean

variance_n = M2/n         # Sample variance
variance = M2/(n - 1)     # Unbiased estimate of population variance

(来源:http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance)

对于您指出的问题,这似乎更好与通常的算法.

猜你在找的C#相关文章