2017-08-13 6 views
1

Javaで2つの浮動小数点数を掛ける正確な方法を探していましたが、BigDecimalを使うべきですが、期待通りに動作しません。私は間違って何をしていますか?Javaで2つの数値を正確に掛ける

マイコード:

BigDecimal a = new BigDecimal(3.53); 
BigDecimal b = new BigDecimal(3.59); 
BigDecimal c = a.multiply(b); 

System.out.println(c); 

結果:

12.672699999999998796873512674210388041622697702955394242845497954075284496866515837609767913818359375 

期待される結果:

12.6727 
+4

「a」と「b」を印刷してください。 –

+1

私はそれが同じ結果であることを見て、期待値は上記の値の丸め値です。** Math.round ** –

+0

のようなものを使うことができます。最初の浮動小数点定数は正確ではありません。深い理解が必要です。 –

答えて

12

あなたがBigDecimal(double)コンストラクタを使用する場合、それは、doubleよりもより正確に使用することはできません代わりにStringフォーム。同様に、

12.6727 

を出力

BigDecimal a = new BigDecimal("3.53"); 
BigDecimal b = new BigDecimal("3.59"); 
BigDecimal c = a.multiply(b); 
System.out.println(c); 

リンクのJavadocは、部分的に述べている -

注:

  1. このコンストラクタの結果は予想外である可能性が。新しいBigDecimal(0.1)をJavaで記述すると、正確に0.1に等しいBigDecimalが作成されます(スケールされていない1の値、1のスケール)。実際には0.1000000000000000055511151231257827021181583404541015625に等しくなります。これは、0.1を正確にdouble(または、そのためには、任意の有限長の2進数部分)として表すことができないためです。したがって、コンストラクタに渡されている値は、正確には0.1には等しくなく、外観にもかかわらずです。

  2. Stringコンストラクタは、他の一方で、完全に予測可能である:new BigDecimal("0.1")は予想されるように、0.1に等しい正確でのBigDecimalを作成書き込みます。したがって、一般的には、String constructorを優先して使用することをお勧めします。

+0

「BigDecimal a = BigDecimal」はどうですか? valueOf(3.53d); " ? そのようにすれば、実際のdouble変数をStringに変換する代わりに使用することができますが、依然として精度は保持されます。 – Mikemike

+0

@Mikemikeこれはまだ悪い考えです。最初にダブルスを使うことが問題です。文字列とBigDecimalを使用して、間に二重に触れることはありません。あまりにも正確な倍数でこのアプローチを使用すると、間違った結果が得られます。 –

+0

@Louis Wasserman何とか正しい結果が得られました: BigDecimal a = BigDecimal.valueOf(3.53d); BigDecimal b = BigDecimal.valueOf(3.59d); BigDecimal c = a.multiply(b); \t \t System.out.println(c); // 12.6727 – Mikemike

関連する問題