-1.2から1.2まで0.4刻みで、ファイルに出力するプログラムで、
"0"になって欲しいところで、"-1.11022e-016"となってしまいます。
これは、何が原因でしょうか?よろしくお願いします。
環境はWindowsXP, Visual Studio.NET 2003 です。
/********************* 以下、プログラム *********************/
#include<iostream>
#include<fstream>
using namespace std;
#define PARAM_1_START -1.2
#define PARAM_1_END -1.201
#define PARAM_1_STEP 0.4
int main(void)
{
int filenum = FIRST_FILE_NUM ;
ofstream file;
double param_1;
file.open("test.dat");
for(param_1=PARAM_1_START; param_1<=PARAM_1_END; param_1+=PARAM_1_STEP){
file << "x " << param_1 << "\n";
}
}
}
file << endl;
file.close();
return EXIT_SUCCESS;
}
誤差です。0.333.... は正確に1/3ではないために、3倍しても1にはならんのと同じ。
返信ありがとうございます。
一般的には、どうやって回避するのが適当でしょうか?
回避できないので(たとえば四捨五入して)誤魔化すことになります。
0.999999 や 1.0000001 を 1.0 に丸めることになります。
精度と値域に問題がなければ、整数型で「げた」を履かせて演算する場合もあります。
↑
-1.2 => 1200
0.4 => 400
-1200 + 400 => -(800 / 1000)
-800 + 400 => -(400 / 1000)
-400 + 400 => 0
0 + 400 => 400 / 1000
400 + 400 => 800 / 1000
800 + 400 => 1200
てな感じだと。
計算機で数値計算を行う場合、さらに、割り算は最後にまとめて行うように式を変形したりもしますね。
long buffer[100];
long d = -1200, m = 400, v = 1200;
int idx=0;
//計算だけ
while (d < v) {
d += m;
buffer[ idx++ ] = d;
}
//↑最後に纏めて"数値計算を行う"場合の例、平均値の割り出しとか。
long av = 0;
for (int i=0;i < idx;i++) {
av += buffer[ i ];
}
fprintf(stdout, "average = %.2f", (double)av / (double)1000);
fprintf(stdout, "---- result ----\n");
for (int i=0;i < idx;i++) {
fprintf(stdout, "%.2f", (double)buffer[ i ] / (double)1000);
}
# 平均を求める、ってのはあくまでも例ってことで。
επιστημηさん、渋木宏明(ひどり)さん、mあさん
ご返信ありがとうございます。
プログラムまで書いていただいて恐縮です。
基本的には解決されなくて、
それを補うためにみなさん色々工夫(特に四捨五入)なさっているということが、
わかりました。
とりあえず、僕のプログラムも、
整数で計算して、その後doubleに落とすかっこうで
行いたいと思います。
本当にありがとうございました。
解決チェック忘れました。すいません。
解決チェック忘れました。すいません。
ツイート | ![]() |