2011-12-09 15 views
0

浮動小数点数をC++で使用し、forループのインクリメントとして数字を0.1の倍数として使用すると何度か起こります。ループ反復子は正確に0.1の倍数ではありませんが、予測不可能に他の加算または減算された1^-17の小数があります。どうすればそれを避けることができますか?浮動小数点数を扱うときに不規則な小さな数値を避ける

+5

浮動小数点を反復処理に使用しないでください。 – Pubby

+0

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html –

+0

反復に*正確でない*浮動小数点を使用しないでください。 0.125のような正確な数値は、IEEE 754バイナリでは問題ありません(もちろん、十分な数の範囲にとどまっている限り)。 – kennytm

答えて

6

浮動小数点数を反復処理しないでください。

浮動小数点で0.1を正確に表すことができないという問題があります。したがって、代わりに次のようなものを実行する必要があります。

+2

一番良いのは、毎回「0.1」を追加しているからです。論理的に正確に表現可能な数字になっても(たとえば「1.0」のように)、彼はそうでないかもしれません。だから 'for(float f = 0.0f; f <1.0; f + = 0.1f)'のような行は、9回しか反復しないかもしれません。 – corsiKa

7

整数を反復に使用し、使用する前に浮動小数点数を掛けてください。

小数点の数学パッケージを見つけ、浮動小数点の代わりに使用します。

+0

マークが死んでいます。 – EvilTeach

1

浮動小数点を扱う場合の、excellent articleです。正確にあなたの例をカバーする議論があります - 0.1の増分:

for (double r=0.0; r!=1.0; r+=0.1) printf("*"); 

それが印刷しようとしているどのように多くの星は?十?それを実行して驚かせてください。このコードは、私たちがそれを打破するまで星を印刷し続けます。

問題はどこですか?すでにわかっているように、倍精度は無限に正確ではありません。我々がここで遭遇した問題は次のとおりです。バイナリでは、0.1の表現は有限ではありません(ベース10にあるように)。 10進数0.1は2進数0.0(0011)に相当し、かっこ内の部分は永遠に繰り返されます。 0.1がdouble変数に格納されると、最も近い表現可能な値に丸められます。したがって、10回追加すると、結果は1に正確には等しくなりません。

浮動小数点数が多い場合は、記事全体を読むことを強くお勧めします。

関連する問題