足し算が0にならないのは?

解決


ぬこ  2007-05-25 07:11:16  No: 65185

-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;
}


επιστημη  2007-05-25 09:55:40  No: 65186

誤差です。0.333.... は正確に1/3ではないために、3倍しても1にはならんのと同じ。


ぬこ  2007-05-25 10:16:12  No: 65187

返信ありがとうございます。
一般的には、どうやって回避するのが適当でしょうか?


επιστημη  2007-05-25 10:27:17  No: 65188

回避できないので(たとえば四捨五入して)誤魔化すことになります。
0.999999 や 1.0000001 を 1.0 に丸めることになります。


渋木宏明(ひどり)  URL  2007-05-25 15:14:24  No: 65189

精度と値域に問題がなければ、整数型で「げた」を履かせて演算する場合もあります。


mあ  2007-05-25 19:10:43  No: 65190


-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

てな感じだと。


渋木宏明(ひどり)  URL  2007-05-25 20:20:36  No: 65191

計算機で数値計算を行う場合、さらに、割り算は最後にまとめて行うように式を変形したりもしますね。


mあ  2007-05-25 20:50:30  No: 65192

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);
}

# 平均を求める、ってのはあくまでも例ってことで。


ぬこ  2007-05-26 07:38:35  No: 65193

επιστημηさん、渋木宏明(ひどり)さん、mあさん
ご返信ありがとうございます。
プログラムまで書いていただいて恐縮です。

基本的には解決されなくて、
それを補うためにみなさん色々工夫(特に四捨五入)なさっているということが、
わかりました。

とりあえず、僕のプログラムも、
整数で計算して、その後doubleに落とすかっこうで
行いたいと思います。

本当にありがとうございました。


ぬこ  2007-05-26 07:38:59  No: 65194

解決チェック忘れました。すいません。


ぬこ  2007-05-26 07:39:01  No: 65195

解決チェック忘れました。すいません。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加