2015-12-19 4 views
7

このコードを考えてみましょう:コードは無限ループに実行しないのはなぜのD == 9000000000000000000d無限ループ

double d = 9000000000000000000d; 
while (d == 9000000000000000000d) 
{ 
    d += 500; 
    Console.WriteLine(d); 
} 

を?

はなぜコンパイラは、任意の例外をスローしないのですか?

+18

ダブルは15桁の有効数字を格納できます。 500を追加するだけでは値を変更できません。デバッガで簡単に表示できるもの。 –

+0

'Console.WriteLine'の出力を表示できますか?ちょっと待ってください... –

+1

@RenéVogtConsole.WriteLine print 9E + 18 –

答えて

19

A二重、すなわち上位ビットの固定数、変化する精度を有しています。

ダブル/浮動小数点数(浮動小数点数)指数及び(IEEE754標準参照)mantisseから成ります。論理が大きいということは、大きい数字の場合は小さな数字に対しては高い精度を必要としないが、小さい数字に対しては高い精度が必要であるということである。したがって、+1は大量のために何もしませんのでd==d+1が真であることがあります(should not use floating point numbers for representing money)。4*0.1!=0.4が実際と異なる可能性があるため、浮動小数点数の比較にも問題があります。これはIEEE754標準で定義されているため、例外をスローしません(btwコンパイラは警告またはエラーを発行できますが、例外は発生しません)。

常に1の精度を持つ整数とは対照的です。したがって、精度が1の大きな数値を処理する必要がある場合は、BigIntegerの実装を使用するか、decimalを固定小数点と固定精度のセットで使用することを検討する必要があります。