在C ++中检查溢出为double的平均值

时间:2013-02-14 09:26:37

标签: c++

我必须在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()); 
} 

}; 

以下是我的问题:

  1. 如何确保double的值不会溢出并返回 零。
  2. 我如何检查我没有交叉总和的最大值,即 双倍最大值?

3 个答案:

答案 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;