float
CPUの浮動小数点ユニット( 、、 )でネイティブにサポートされている固定精度の浮動小数点型は、double
指定real
した例のように、何桁もの精度を必要とする計算には最適ではありません。
問題は、これらの浮動小数点型の精度が有限の桁数(実際には2桁)であるため、このようなデータ型で表すことができる数値の長さが制限されることです。このfloat
タイプには、小数点以下7桁の制限があります(例:3.141593)。タイプは14に制限されていdouble
ます(例:3.1415926535898)。タイプにも同様の制限がありreal
ます(の制限よりわずかに多いdouble
)。
したがって、浮動小数点値に非常に小さい数値を追加すると、それらの桁が失われます。次の2つのfloat値を合計するとどうなるかを見てください。
float a = 1.234567f, b = 0.0000000001234567
float c = a + b;
writefln("a = %f b = %f c = %f", a, b, c);
a
とは両方ともb
有効な浮動小数点値であり、個別に約7桁の精度を保持します。ただし、追加すると、フロートに押し戻されるため、最前面の7桁のみが保持されます。
1.2345670001234567 => 1.234567|0001234567 => 1.234567
^^^^^^^^^^^
sent to the bit bucket
したがって、加算からの精度のより細かい桁が打ちのめさc
れるため、に等しくなります。a
a
b
これが概念の別の説明です。おそらく私のものよりはるかに優れています。
この問題に対する答えは、任意精度の演算です。残念ながら、任意精度演算のサポートはCPUハードウェアにはありません。したがって、(通常は)プログラミング言語ではありません。ただし、任意精度の浮動小数点型とそれらに対して実行する計算をサポートするライブラリは多数あります。いくつかの提案については、この質問を参照してください。今日、この目的のためのD固有のライブラリはおそらく見つかりませんが、単独で使用するのに十分簡単なはずのCライブラリ(GMP、MPFRなど)がたくさんあります。それらの1つのDバインディング。