【发布时间】:2015-07-09 21:25:00
【问题描述】:
我尝试用下一种方法计算标准差:
private static double? StdDev(IReadOnlyCollection<double> items) {
if(items == null) {
throw new ArgumentNullException("items");
}//if
var count = items.Count;
if(count == 0 || count == 1) {
return null;
}//if
var sum = 0d;
var sqrsum = 0d;
foreach(var item in items) {
sum += item;
sqrsum += item * item;
}//for
var average = sum / count;
var stddev = Math.Sqrt((sqrsum - count * average * average) / (count - 1));
return stddev;
}
有时,表达式“sqrsum - count * average * average”小于 0,Math.Sqrt 返回 NaN。例如,在这种情况下:
private static void Main() {
var data = Enumerable.Repeat(86.399999999999991, 3).ToList();
var stddev = StdDev(data);
Console.WriteLine("StdDev = " + stddev);
}
如何在我的代码中解决这种情况?我应该使用 Math.Abs(sqrsum - count * average * average) 还是应该四舍五入?
【问题讨论】:
-
您可以在循环内平方之前从项目中减去平均值,然后在最后取 sum/N 的 sqrt。
-
@folkol 谢谢,但我想要单项迭代。
-
那么我猜你会遇到这样的数字错误。您始终可以在 sqrt:ing 之前检查负数并返回 0。
-
@folkol 谢谢!可能是另一个“如果”还不错。
-
不,它可能工作正常 :) (虽然,计算标准的数值方法的约定是在平方之前进行减法......由于您在上面遇到的原因。)
标签: c# .net floating-point floating-accuracy