浮動小数点変数を使用すると「エラー」と聞いたことがあります。今私はこのパズルを解こうとしています、そして私はいくつかの丸め/浮動小数点エラーを受け取っていると思います。だから私は最終的に浮動小数点エラーの基本を理解するつもりです。
浮動小数点/丸めエラーの簡単な例は何ですか(できればC++で)?
編集:たとえば、成功確率pのイベントがあるとします。私はこのイベントを10回行います(pは変化せず、すべての試行は独立しています)。正確に2つの試験が成功する確率はどれくらいですか?私はこれを次のようにコード化しています:
double p_2x_success = pow(1-p, (double)8) * pow(p, (double)2) * (double)choose(8, 2);
これは浮動小数点エラーの機会ですか?
絵は千の言葉に値する-方程式f(k)
を描いてみてください:
そして、そのようなXYグラフが表示されます(XとYは対数スケールです)。
コンピュータが丸め誤差なしで32ビットの浮動小数点数を表すことができる場合、k
ごとにゼロを取得する必要があります。ただし、浮動小数点誤差の累積により、kの値が大きくなると誤差が増加します。
ああ!
for(double d = 0; d != 0.3; d += 0.1); // never terminates
一般に、浮動小数点エラーは、IEEE浮動小数点表現に格納できない数値を指します。
整数は、右端のビットが1で格納され、左側の各ビットは2倍(2、4、8、...)です。これが2 ^ nまでの整数を格納できることは簡単です。ここで、nはビット数です。
浮動小数点数の仮数(小数部)も同様に格納されますが、左から右に移動し、連続する各ビットは前のビットの値の半分になります。 (実際にはこれより少し複雑ですが、今のところはそれで十分です)。
したがって、0.5(1/2)のような数値は簡単に格納できますが、1/2、1/4、1/8、...という形式の固定数の分数を追加することで、1未満のすべての数値を作成できるわけではありません。
本当に簡単な例は0.1、つまり1/10です。これは無制限のシリーズで実行できます(実際に問題を解決することはできません)が、コンピューターが0.1を格納するときは常に、格納されているのはこの数値ではありません。
Unixマシンにアクセスできる場合、これは簡単に確認できます。
Python 2.5.1 (r251:54863, Apr 15 2008, 22:57:26)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 0.1
0.10000000000000001
>>>
フロートとダブルを使用した等価テストでは、どの言語を使用していても十分に注意する必要があります。
(例として、0.2はIEEEバイナリに格納できない厄介な数値の1つですが、p <= 0.2のような等式ではなく不等式をテストしている限り、問題はありません。)
しばらく前に私を捕まえたシンプルなCの1つ、
char *c = "90.1000";
double d = 0;
sscanf(c,"%f",&d);
printf("%0.4f",d);
>> 90.0999
これは、DMSの角度をラジアンに変換する関数にありましたが、上記の場合はそうではありませんでした。
これが私を捕まえたものです。
round(256.49999) == 256
roundf(256.49999) == 257
ダブルスとフロート..
私はPythonインタプリタからこれを好きです:
Python 2.7.10 (default, Oct 6 2017, 22:29:07)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 0.1+0.2
0.30000000000000004
>>>
超シンプル:
a = 10000000.1
b = 1/10
print(a - b == 10000000)
print ('a:{0:.20f}\nb:{1:.20f}'.format(a, b))
(プラットフォームに応じて)次のように出力します。
False
a:10000000.09999999962747097015
b:0.10000000000000000555