-3

Java Puzzlers のコードを楽しんでいるときに (私は本を持っていません)、このコードに出くわしました。

public static void main(String args[]) {
        System.out.println(2.00 - 1.10);
    }

出力は

0.8999999999999999

コードを次のように変更しようとしたとき

2.00d - 1.10dそれでも私は同じ出力を得ます0.8999999999999999

用、2.00d - 1.10fアウトプットは0.8999999761581421
用、2.00f - 1.10dアウトプットは0.8999999999999999
用、2.00f - 1.10fアウトプットは用0.9

そもそも出力が得られないのはなぜ0.9ですか? 私はこれから頭も尻尾も作ることができませんでしたか?誰かがこれを明確にできますか?

4

3 に答える 3

6

Java では double 値はIEEE 浮動小数点数であるためです。

回避策は、 Big Decimal クラスを使用することです

不変の任意精度の符号付き 10 進数。BigDecimal は、スケーリングされていない任意精度の整数値と 32 ビットの整数スケールで構成されます。ゼロまたは正の場合、位取りは小数点以下の桁数です。負の場合、数値のスケーリングされていない値は、10 のスケールの負の累乗で乗算されます。したがって、BigDecimal で表される数値の値は (unscaledValue × 10^-scale) です。

ちなみに、ほとんどのシステムで浮動小数点数がどのように格納されているかについては、IEEE 754 に関するウィキペディアの記事も参照してください 。

浮動小数点数に対して行う操作が多いほど、丸め誤差が大きくなる可能性があります。

于 2013-09-29T13:26:30.507 に答える
5

バイナリ 0.1 は 0.00011001100110011001100110011001.....

そのため、バイナリで正確に表現することはできません。四捨五入する場所 (float または double) に応じて、異なる答えが得られます。

したがって 0.1f =0.000110011001100110011001100 そして 0.1d=0.0001100110011001100110011001100110011001100110011001

数が 1100 サイクルで繰り返されることに注意してください。ただし、浮動小数点数と倍精度は、サイクルの別の時点で分割されます。そのため、一方では誤差が切り上げられ、他方では切り捨てられます。違いにつながります。

しかし、最も重要なことです。 浮動小数点数が正確であると仮定しないでください

于 2013-09-29T13:27:51.357 に答える
2

他の答えは正しいです。有効な参照を指すためだけに、私はoracle docを引用します:

double: double データ型は、倍精度の 64 ビット IEEE 754 浮動小数点です。その値の範囲は、この説明の範囲を超えていますが、Java 言語仕様の浮動小数点型、形式、および値のセクションで指定されています。10 進数値の場合、通常、このデータ型がデフォルトの選択です。前述のとおり、 このデータ型は、通貨などの正確な値には使用しないでください。

于 2013-09-29T13:32:24.583 に答える