0

Visual C++ 2008 Express Edition を使用していて、コードをデバッグするとき:

double x = 0.2;

x 0.20000000000000001 のデバッグ ツールチップに表示されます

しかし:

typedef numeric_limits< double > double_limit; 
int a = double_limit::digits10

私に与えます:a = 15

デバッガーの結果が通常の C++ 精度よりも長いのはなぜですか? この奇妙な精度は何に基づいているのでしょうか?

私のCPUはIntel Core 2 Duo T7100です

4

3 に答える 3

3

これを読む必要があります:すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと

于 2010-03-18T19:08:19.907 に答える
1

表示されているのは、実数 (浮動小数点を読み取る) をバイナリ コンピューターで完全な精度と正確さで表現できないという事実が原因です。これは人生の事実です。代わりに、コンピュータが値を概算し、定義された形式でメモリに格納します。

最近のほとんどのマシン (MSVC Express を実行しているマシンを含む) の場合、この形式はIEEE 754です。

簡単に言えば、IEEE 754 で実数を格納する方法は次のとおりです。1 つの符号ビット、8 つの指数ビット、および 23 の小数ビットがあります (floatデータ型doublesの場合、それに応じてより多くのビットを使用しますが、形式は同じです)。このため、完璧な精度と精度を実現することはできません。幸いなことに、重要な金融システムや科学システムなど、ほぼすべてのアプリケーションで十分な精度と精度を実現できます。

コードで浮動小数点を使用できるようにするために、IEEE754 について知っておくべきすべてのことを知る必要はありません。ただし、知っておく必要があることがいくつかあります。

1) 浮動小数点の計算と格納に固有の丸め誤差のため、2 つの浮動小数点値を等しいかどうか比較することはできません。代わりに、次のようにする必要があります。

double d = 0.2;
double compare = 0.000000001;

double d2 = something;

if( (d - d2 < compare) && (d2 - d < compare) )
{
  // numbers are equal
}

2) 丸め誤差の複合。浮動小数点値に対して操作を実行する回数が増えるほど、精度が失われます。

3) 大きさが大きく異なる 2 つの浮動小数点を追加することはできません。たとえば、1.5x10^30 と 1.5x10^-30 を加算して 60 桁の精度を期待することはできません。

于 2010-03-18T19:22:14.940 に答える
0

double リテラル0.2が与える正確な値は、0.200000000000000011102230246251565404236316680908203125 です。

double を出力するほとんどの関数は、一定量の 10 進数の後にカットします。そのため、0.2実際に 0.2 を生成するという錯覚に陥っています。

正確な値を取得する方法は次のとおりです。

public static void main(String[] args)
{
    System.out.println(new java.math.BigDecimal(0.2));
}
于 2010-03-18T19:33:26.533 に答える