@Jerry Coffin
我得到逻辑, while(文件>>值)//而刚从文件中获取的输入为true ....做计算。 然而,当我实施这个时,计数器只进入1&它的价值非常高。有时是错的,但我不知道是什么。该文件有效
File.open(FileName, ifstream::in);
while(File>>value){
++counter;
sum += value;
sumsqr+= value * value;
}
average=sum/counter;
variance = sumsqr/counter - average*average;
File.close();
这是我正在使用“text.txt”的输入文件的内容 23244564 1486415241250586205864104818638684840823244564 1486415241250586205864104818638684840823244564 1486415241250586205864104818638684840823244564 1486415241250586205864104818638684840823244564 1486415241250586205864104818638684840823244564 1486415241250586205864104818638684840823244564 1486415241250586205864104818638684840823244564 1486415241250586205864104818638684840823244564 1486415241250586205864104818638684840823244564 14864152412505862058641048186386848408
答案 0 :(得分:4)
可悲的是,(至少)有三个答案引用了你的while (!File.eof())
,而没有评论这是完全错误的事实。你想要的是这样的:
while (File>>value) {
++counter;
sum += value;
sumsqr += value * value;
}
average = sum/counter;
variance = sumsqr/counter - average * average;
使用while (!File.eof())
的错误是阴险的 - 您通常会得到看起来合理的结果,并且实际上相当接近正确。问题是{I} eof()
在您尝试从文件中读取之后才会变为真,并且尝试的读取失败。当它失败时,value
仍将具有您读取的最后一个值,因此它的行为就像列表中的最后一个数字确实存在两次(例如,如果您的文件包含21个数字,则您的循环将执行22次,并且在22 nd 迭代中,它将再次使用21 st 数字)。这会使你的计算稍微偏离,但通常不够明显 - 几乎是最糟糕的错误。
编辑:这是一个完整的测试程序:
#include <fstream>
#include <iostream>
double variance(std::istream &File) {
double value, average, sum, counter, sumsqr, variance;
while (File>>value) {
++counter;
sum += value;
sumsqr += value * value;
}
average = sum/counter;
variance = sumsqr/counter - average * average;
return variance;
}
double variance2(std::istream &File) {
double value, average, sum, counter, sumsqr, variance;
while (!File.eof()) {
++counter;
File >> value;
sum += value;
sumsqr += value * value;
}
average = sum/counter;
variance = sumsqr/counter - average * average;
return variance;
}
int main() {
std::ifstream in("data.txt");
double v1 = variance1(in);
in.clear();
in.seekg(0);
double v2 = variance2(in);
std::cout << "Using \"while (file>>value)\"" << v1 << "\n";
std::cout << "Using \"while (!file.eof())\"" << v2 << "\n";
return 0;
}
以下是一些测试数据:
1
2
3
4
5
6
7
8
9
10
当我对这些数据运行时,我得到:
Using "while (file>>value)": 8.25
Using "while (!file.eof())": 9.17355
作为交叉检查,我使用两组数据在Excel中进行了计算:
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
8.25 10
9.173553719
每列中的最后一行是对前面数据执行“VARP”的公式的结果。请注意,我的函数与Excel为正确的输入数据生成的函数匹配。使用while (!file.eof())
的函数与Excel生成的函数匹配,最后一个数字是重复的。
我甚至无法猜测是什么让环路只运行一次而且读取的值不正确。如果不能猜测或重现问题,我恐怕无法提供有关如何解决问题的有用建议。
答案 1 :(得分:1)
您的方差计算完全不正确。在统计学方面,方差是
E(x^2) - [E(x)^2]
所以摆脱第二个循环(我甚至不确定你认为它做了什么)并将第一个循环更改为:
while(!File.eof()){
counter++;
value = File.get();
sum += value;
sumsqr += value*value;
}
average = sum/counter;
variance = (sumsqr/counter) - (average*average);
编辑:Jerry Coffin的answer甚至更好,因为它展示了eof()
的问题。
答案 2 :(得分:0)
variance=counter*(average*average)
答案 3 :(得分:0)
在第二个!File.eof()
循环中,您没有从文件中读取。方差不是值与平均值之差的平方和吗?您的循环根本不会查看文件中的值。此外,使用整数变量求和,平均值和方差可能会导致不准确;你可能想要double
代替那些人。
答案 4 :(得分:0)
while(!File.eof()){
variance +=(average*average);
}
以上几行似乎没有多大意义。你不是在读那块东西时读的东西。这个while块不会终止。
答案 5 :(得分:0)
好吧,如果问题没有限制你可以使用哪些库我建议使用Boost Accumulators使这类事情变得微不足道。
你得到方差,均值,以及你想要的任何其他基本统计值。他们在使用long double
时遇到了一些问题,但是他们很棒!