问题
I was searching for a precise way to multiply two floating point numbers in Java, and I read that I should use BigDecimal, however it doesn't work as expected. What am I doing wrong?
My code:
BigDecimal a = new BigDecimal(3.53);
BigDecimal b = new BigDecimal(3.59);
BigDecimal c = a.multiply(b);
System.out.println(c);
Result:
12.672699999999998796873512674210388041622697702955394242845497954075284496866515837609767913818359375
Expected result:
12.6727
回答1:
When you use a BigDecimal(double) constructor it cannot be more precise than a double
, use the String
form instead. Like,
BigDecimal a = new BigDecimal("3.53");
BigDecimal b = new BigDecimal("3.59");
BigDecimal c = a.multiply(b);
System.out.println(c);
Which outputs
12.6727
The linked Javadoc says in part -
Notes:
The results of this constructor can be somewhat unpredictable. One might assume that writing new
BigDecimal(0.1)
in Java creates aBigDecimal
which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to0.1000000000000000055511151231257827021181583404541015625
. This is because 0.1 cannot be represented exactly as adouble
(or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.The String constructor, on the other hand, is perfectly predictable: writing
new BigDecimal("0.1")
creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.
来源:https://stackoverflow.com/questions/45663315/multiply-two-numbers-precisely-in-java