5
public static void main(String[] args) {
    // TODO Auto-generated method stub
    BigDecimal foo,foo1;
    foo=BigDecimal.valueOf(3.1);
    foo1=BigDecimal.valueOf(3.1f);

    System.out.println(foo);
    System.out.println(foo1);

}

結果:
3.1
3.0999999046325684

なぜ結果が異なるのですか?JDK1.7.0_03を使用しています

4

4 に答える 4

5

3.1doublewhileを定義し、を3.1f定義しfloatます。表示されるのは、その値を表す際の問題floatです(floatは「のみ」の32ビットとダブル64ビットを使用します)。

3.1正確に使用して定義する場合BigDecimalは、Stringコンストラクターを使用します。

BigDecimal foo = new BigDecimal("3.1");
System.out.println(foo);

出力:

3.1
于 2012-07-19T09:32:49.063 に答える
0

問題は、floatとdoubleの両方で、数値の整数部分と小数部分の両方の表現にそれぞれ32ビットと64ビットを使用していることです。問題は、実際には2進ビットで正確な10進表現を持たない小数値を表現しようとしたときに発生します。

.1を例にとると、これを基数2で正確に表す方法はありません。それ以上に、基数10で1/3を正確に表す方法があります。

したがって、Javaはいくつかのトリックを使用して、次のように言います。

float f = 3.1;
System.out.println(f);

正しい番号を出力します。ただし、これらの値を使用して算術演算を開始すると、丸め誤差が発生します。

BigDecimalは、異なる表現を使用するため、正確です。これは、BigInteger(int []を使用して巨大な数値を表す)を内部的に格納します。次に、精度値を使用して、小数点以下の整数桁の数を示します。

たとえば、値3.1はBigDecimalで31、precision = 1として表されます。このため、BigDecimalは、floatとdoubleの同じ丸めの問題に悩まされることはありません。

ただし、float / double値を使用してBigDecimalを初期化すると、同じ丸め誤差がBigDecimalインスタンスに入ります。そのため、文字列を使用して値を作成することをお勧めします。

于 2012-07-19T13:17:28.203 に答える
0

floatdoubleは、精度の異なるさまざまなタイプです。

BigDecimal.valueOf(double)は、の表現エラーを修正できますが、修正はできdoubleません。float

特別なfloat理由がない限り、IMHOは使用しません。

于 2012-07-19T09:34:19.810 に答える
0

私が共有したかった新人の間違いのために私は同様の問題を抱えていました:

BigDecimal bd = new BigDecimal(float); 

これは、私が望まなかった余分な精度を与え、それを文字列に設定すると修正されました...

しかし、私はこれをしていました:

BigDecimal bd = new BigDecimal(float);
bd.setScale(2, RoundingMode.HALF_UP);

ルーキーの間違い。私はこれをすべきだった。

bd = bd.setScale(2, RoundingMode.HALF_UP);
于 2014-02-06T17:46:34.837 に答える