我必须在C ++中实现标准差和方差。
#include <iostream>
#include <string>
#include <math.h>
class StdDeviation
{
private:
int max;
double value[100];
double mean;
public:
double CalculateMean()
{
double sum = 0;
for(int i = 0; i < max; i++)
sum += value[i]; // Question 1. at bottom.
return (sum / max);
}
double CalculateVariane()
{
mean = CalculateMean();
double temp = 0;
for(int i = 0; i < max; i++)
{
temp += (value[i] - mean) * (value[i] - mean) ;
}
return temp / max;
}
double CalculateSampleVariane()
{
mean = CalculateMean();
double temp = 0;
for(int i = 0; i < max; i++)
{
temp += (value[i] - mean) * (value[i] - mean) ;
}
return temp / (max - 1);
}
int SetValues(double *p, int count)
{
if(count > 100)
return -1;
max = count;
for(int i = 0; i < count; i++)
value[i] = p[i];
return 0;
}
double GetStandardDeviation()
{
return sqrt(CalculateVariane());
}
double GetSampleStandardDeviation()
{
return sqrt(CalculateSampleVariane());
}
};
以下是我的问题:
答案 0 :(得分:2)
你确定溢出是一个问题吗? double的最大值为1.7 * 10 308 。你是求和的,但是如果你的值不超过~10 150 ,你甚至还是安全的。你真的有这样的价值吗?
更严重的问题是舍入错误。 double
保留大约17位有效数字(确切地说是52位有效二进制数字)。如果添加指数不同的数字,则较小部分的下半部分仅影响超出结果精度的数字。极端1E20 + 1 == 1E20
,因为要表示不同的数字,这将需要20位有效数字而你没有它们。当你可能有很多小数字和少数大数字时,建议先添加小数字。
答案 1 :(得分:1)
在c ++ 11中
double CalculateMean()
{
double sum = 0;
for(int i = 0; i < max; i++)
{
sum += value[i];
if(isinf(sum))
{
//handle error
}
}
return (sum / max);
}
请参阅:isinf
但是,如果迭代计算前缀的平均值,则可以完全避免这个问题(对于平均计算):
double CalculateMean()
{
double mean = 0;
for(int i = 0; i < max; i++)
{
mean *= ((double)i/(double)(i+1));
mean += value[i]/(i+1);
}
return mean;
}
现在意味着只有等于无穷大,如果值在其中具有以
开头的infinte值答案 2 :(得分:0)
double avg = 0;
for (int i = 0; i < max; ++i)
avg += value[i] / max;