1

重複の可能性:
JavaScript の数学は壊れていますか?
浮動小数点数の精度の問題への対処

以下のコードとその出力を検討してください。

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cmath>
#include <limits>
#include <vector>


int main(int argc, char *argv[])
{
  double xleft  = 0;
  double xright = 1.0;

  double dx = 0.1;
  std::cout << std::setprecision(36) << "dx is " << dx << std::endl; 

  int numgridpts = ((int) ceil (( xright - xleft )/dx))  + 1; 


  for (int i = 0; i < numgridpts  ; ++i)
    {
      std::cout << std::setprecision(36) << xleft + i*dx << std::endl;
    }

  return 0;
}

[~:ICgen/$ ./a.out                                                                                                                               
dx is 0.100000000000000005551115123125782702
0
0.100000000000000005551115123125782702
0.200000000000000011102230246251565404
0.300000000000000044408920985006261617
0.400000000000000022204460492503130808
0.5
0.600000000000000088817841970012523234
0.700000000000000066613381477509392425
0.800000000000000044408920985006261617
0.900000000000000022204460492503130808
1

私の質問は、36 ビットの精度まで数字を出力するときです。数字 0 、 0.5 、および 1.0 が正確に表されているのはなぜですか?

また、上記の出力に示すように 0.2 と 0.1 の浮動小数点表現を追加すると、ガベージ ビットの部分で 0.3 の表現に加算されないようです。

Linux Ubuntu 10.10 と gcc コンパイラを使用しています

4

1 に答える 1

5

これらはガベージ数ではありませんが、IEEE 754 標準に従って、浮動小数点表現内でこれらの数値の可能な限り正確な値を示します。

その標準は、10 進数ではなく 2 進数を使用します。したがって、1/2、1/4、1/8 (= 0.5、0.25、0.125、...) などの分数とその倍数は正確に表されますが、1/3 や 1/10 などの分数は正確に表されません。

これが 10 進数システムである場合、1/10、1/100、1/1000 などの分数とその倍数だけが、有限の桁数で正確に表される数になります。

どちらのシステムでも、極端に大きくない限り、すべての整数は正確に表現されます。

于 2012-04-04T21:02:42.293 に答える