悲しいことに、(少なくとも) 3 つの回答があなたを引用していますwhile (!File.eof())
が、これは明らかに間違っているという事実についてはコメントしていません。あなたが望むのは次のようなものです:
while (File>>value) {
++counter;
sum += value;
sumsqr += value * value;
}
average = sum/counter;
variance = sumsqr/counter - average * average;
使用によるバグwhile (!File.eof())
は潜行性です。通常、妥当に見える結果が得られ、実際にはかなり正しい結果が得られます。問題はeof()
、ファイルからの読み取りを試行してから読み取りが失敗するまで true にならないことです。失敗した場合value
でも、最後に読み取った値が保持されるため、リストの最後の数字が実際に 2 回存在したかのように動作します (たとえば、ファイルに 21 個の数字が含まれている場合、ループは 22 回実行され、22 回実行されます)。 2回目の反復では、21 番目の数値が再び使用されます)。これにより計算が少し狂いますが、通常はすぐにわかるほどではなく、考えられる最悪の種類のバグです。
編集:これは完全なテストプログラムです:
#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
クロスチェックとして、次の 2 つのデータ セットを使用して、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 が生成するものと一致することに注意してください。関数 usingwhile (!file.eof())
は、Excel が生成するものと一致し、最後の数値が複製されます。
何が起こってループが 1 回だけ実行され、誤った値が読み取られるのかを推測することさえできません。問題を推測したり再現したりすることができないため、修正方法について有益な提案を行うことはできません。