これを Visual Studio 2008 のイミディエイト ウィンドウに入力すると、次のようになります。
? .9 - .8999999999999995
それは私に答えとしてこれを与えます:
0.00000000000000055511151231257827
ドキュメントによると、double の精度は 15 ~ 16 桁ですが、32 桁の精度で結果が得られます。余分な精度はどこから来るのでしょうか?
これを Visual Studio 2008 のイミディエイト ウィンドウに入力すると、次のようになります。
? .9 - .8999999999999995
それは私に答えとしてこれを与えます:
0.00000000000000055511151231257827
ドキュメントによると、double の精度は 15 ~ 16 桁ですが、32 桁の精度で結果が得られます。余分な精度はどこから来るのでしょうか?
答えは 15 ~ 16 桁しかありません。これらの先行ゼロはすべてカウントされません。数値は実際には 5.5511151231257827 × 10 -16のようになります。仮数部には 15 ~ 16 桁の数字があります。指数 (-16) は、小数点を 16 桁シフトするのに役立ちますが、全体の数字の桁数は変更しません。
いくつかのコメントをいただいた後、実際に何が起こっているのか気になります。問題の番号をこのIEEE-754 Converterに接続しました。最後の「27」を「30」に丸める自由がありましたが、結果が変わるとは思いません。
コンバーターは、数値を 3 つのバイナリ部分に分解します。
符号: 0 (正)
指数: -51
有意桁: 1.0100000000000000000000000000000000000000000000000 (1.25 10のバイナリ)
したがって、この数は 1.01 2 × 2 -51または 1.25 10 × 2 -51です。格納されている有効な 2 進数は 3 桁しかないため、Lars が何かに夢中になっている可能性があります。数値が変換されるたびに同じになるため、「ランダムノイズ」になることはありません。
データは、格納されている数字は「5」だけであることを示唆しています。先頭のゼロは指数に由来し、残りの一見ランダムな数字は 2 -51の計算に由来します。
読む必要があります:すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと .
基本的には、浮動小数点数が有限の精度で格納されることに帰着します。いくつかのデルタと比較する必要があります。
if(.9 - .8999999999999995 <= 0.0001)
//close enough to be equal
先頭のゼロは重要ではありません/精度の一部です(浮動小数点数に関する限り、数学的に言えば、それらは重要です)。先頭のゼロは、浮動小数点数の内部表現の指数部分によるものです。
この部分55511151231257827
(仮数または仮数) には 17 桁の 10 進数があり、これは 15 ~ 16 桁に十分近い値です。
@Lars D: あなたが正しいと考えるものは、質問 のコンテキスト内でのみ正しいです。.9 - .8999999999999995
仮数が 0.625、指数が -50 の float になります。0.625 * 2 -50を取ると、5.5511151231257827e-16 になります。ここで、元の質問の文脈から外れて、有効数字が 17 桁の数値が得られました。これはたまたま 0.0000000000000005 の最良の 2 進近似値です。ただし、これらの先行ゼロは、浮動小数点数の表現に関する限り重要ではありません。
? .9 - .8999999999999995
この減算プロセスは、15 ~ 16 桁の有効数字で、次のようになります。
0.0000000000000005
残りの桁は丸め誤差です。ただし、コンピューターは常に最初のゼロ以外の数字の後に 15 ~ 16 桁の有効数字を格納するため、丸め誤差が表示され、丸め誤差によって生成された後続の乱数が大量に発生します。したがって、結果には、減算演算からの 16 桁の有効数字と、結果のストレージからの 16 桁が含まれ、32 桁になります。
「浮動小数点」の「浮動」部分は、5.5511151231257827 * 10^(-16) に近い値を取得していることを意味します。もちろん、内部ではすべて 2 進数で行われているため、正確な表現方法ではありませんが、ポイントは、数値は有効桁数と、基数 (小数点) をどれだけ移動するかを表す数値で表されることです。いつものように、wikipedia で詳細を確認できます。
(2 番目のリンクは、特定のケースに具体的に焦点を当てています。)
バイナリ システムでは、2 で割り切れないため、5 は周期的であるためだと思います。そして、Mark Rushakoff が言ったことが当てはまります。