c#float []平均值失去准确性 [英] c# float [] average loses accuracy

查看:208
本文介绍了c#float []平均值失去准确性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试计算浮点数组的平均值。我需要使用索引,因为它在二进制搜索中,因此顶部和底部将移动。 (大图,我们正在尝试优化半范围估计,因此我们不必在每次通过时都重新创建数组。)

I am trying to calculate average for an array of floats. I need to use indices because this is inside a binary search so the top and bottom will move. (Big picture we are trying to optimize a half range estimation so we don't have to re-create the array each pass).

无论如何,我写了一个自定义的平均循环而且我得到的精度比c#Average()方法低2位。

Anyway I wrote a custom average loop and I'm getting 2 places less accuracy than the c# Average() method

float test = input.Average();

int count = (top - bottom) + 1;//number of elements in this iteration
int pos = bottom;
float average = 0f;//working average
while (pos <= top)
{
     average += input[pos];
     pos++;
}
average = average / count;

示例:


0.0371166766 - c#
0.03711666 - my loop

125090.148 - c#
125090.281 - my loop 

http://pastebin.com/qRE3VrCt

推荐答案


我得到的精度比c#Average()低2位

I'm getting 2 places less accuracy than the c# Average()

否,您仅损失1个有效数字。浮动类型只能存储7个有效数字,其余的只是随机噪声。不可避免地,在这样的计算中,您会累积舍入误差,从而失去精度。

No, you are only losing 1 significant digit. The float type can only store 7 significant digits, the rest are just random noise. Inevitably in a calculation like this, you can accumulate round-off error and thus lose precision. Getting the round-off errors to balance out requires luck.

唯一避免这种情况的方法是使用浮点类型,该浮点类型具有更高的精度来累加结果。没问题,您可以使用 double 。这就是为什么Linq Average方法看起来像这样的原因:

The only way to avoid it is to use a floating point type that has more precision to accumulate the result. Not an issue, you have double available. Which is why the Linq Average method looks like this:

   public static float Average(this IEnumerable<float> source) {
       if (source == null) throw Error.ArgumentNull("source");
       double sum = 0;         // <=== NOTE: double
       long count = 0;
       checked {
           foreach (float v in source) {
               sum += v;
               count++;
           }
       }
       if (count > 0) return (float)(sum / count);
       throw Error.NoElements();
   }

使用 double 重现Linq结果结果中可比较的有效数字位数。

Use double to reproduce the Linq result with a comparable number of significant digits in the result.

这篇关于c#float []平均值失去准确性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆