-1

我必须在 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. 如何检查我没有超过总和的最大值,即最大值的两倍?
4

3 回答 3

2

你确定溢出是一个问题吗?double 的最大值是 1.7*10 308。您正在对平方求和,但即使您的值不超过 ~10 150 ,您仍然是安全的。你真的有这样的价值观吗?

更严重的问题是舍入错误。double保留大约 17 个有效数字(准确地说是 52 个有效二进制数字)。如果添加指数不同的数字,则较小的下半部分仅影响超出结果精度的数字。极端1E20 + 1 == 1E20,因为要表示为不同的数字,这将需要 20 个有效数字,而您没有它们。当您可能会有很多小数字和少数大数字时,建议先添加小数字。

于 2013-02-14T10:15:13.007 回答
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; 
} 

现在 mean 只能等于无穷大,如果值里面有一个 infinte 值开始

于 2013-02-14T09:40:59.067 回答
0
double avg = 0;
for (int i = 0; i < max; ++i)
    avg += value[i] / max;
于 2013-02-14T17:01:31.967 回答