2017-11-04 35 views
0

私はJavaプログラムを作成しています。 4.9E-324/2を実行すると、0.0が返されます。 BigDecimalを使用すると正しい値が返されます。何か不足していますか?4.9E-324/2.0がJavaで0.0を返すのはなぜですか

double x = 4.9E-324/2.0; 
System.out.println(x); //result is zero 
System.out.println(BigDecimal.valueOf(4.9E-324).divide(BigDecimal.valueOf(2.0)).toPlainString()); //result is a non-zero value 
+1

「BigDecimal」が存在する理由のすべてを発見したようです。 「ダブル」は任意の精度を持っていません。 – azurefrog

+1

私は重複した質問の選択に強く同意します。その質問は、ダブルスがなぜ「5.6」のような数字を正確に表すことができないのかという共通の問題を扱っていますが、この質問については「ダブル」の最小限の正の値について何も言及していません。なぜこれが適切な複製物なのか他の誰かが説明できない限り、私はこれを再開します。 – ajb

答えて

1

4.9E-324 /二重は小数点値に対して有する4.94065645841246544e-324Dの限界未満であるためです。

BigDecimalはさらに多くの桁数を保持できるため、そこで動作します。

1

Double.MIN_VALUEの定義が答えを与える。これは、doubleが保持できる最小の正の値であり、2 -1074に等しく、約4.94 * 10 -324です。プログラムに4.9E-324を置くと、コンパイラがこの値を切り上げて使用するのに十分なほど近いです。MIN_VALUEです。あなたは2で割るときには0

理由2 -1074に切り捨てられますので、しかし、その後、結果は、doubleには小さすぎるの最小値は、64ビットのフォーマットに関係していますされていますIEEE 754で指定された浮動小数点数。これは標準形式であり、ほとんどのプロセッサには、その形式の数値に対する計算を実行するためのハードウェアが組み込まれています。 (対照的に、BigDecimalは無制限の長さのJava配列として表現されるため、より精度の高い数値を扱うことができますが、これらの数値の計算はソフトウェアで行われ、doubleの計算よりもはるかに遅くなります)。ビットdoubleは、符号ビットと、11ビットの指数フィールドと、52ビットの仮数とからなる。 「通常」の値の場合、指数フィールドは1から2046までの範囲にあり、実際の指数(2のべき乗)は指数が-1022から1023の範囲になるようにオフセットされています。仮数は1.xxxxxです。 xxxは仮数の52ビットです。この形式で表される値は、1.xxxxx ... xxx * 2 指数です。したがって、最小は、通常の値は1 * 2 -1022またはDouble.MIN_NORMALです。指数フィールドが0で仮数ビットがすべてゼロでない場合、浮動小数点値は値が2 -1022 * 0.xxxxx ... xxxの値を持つ非正規化数です。ここでxは52ビットの仮数フィールド。 (非正規化数は通常のものよりも小さくなることがありますが、通常の倍精度のように52ビットの精度はありません)。したがって、最小の可能な値は2 -1022 * 0.00000 ... 001です。仮数フィールドが52ビット長であるので、この式の最後の部分は2 -52であるため、最小値は2 - (1022 + 52) = 2 -1074となります。

関連する問題