Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BigDecimal Multiplication

I try to multiply two BigDecimal Values with multiply methods as follows,

BigDecimal dur = BigDecimal.valueOf(60/1.1);
BigDecimal bal = BigDecimal.valueOf(1.1);

BigDecimal ans  = dur.multiply(bal);

System.out.println("Ans:"+ans);

I am excepting ans as 60. But i got it as,

Ans:59.999999999999994

Why this comming and how can we resolve it.

like image 797
Rakesh KR Avatar asked Jan 08 '23 12:01

Rakesh KR


2 Answers

The problem is you have a value which can't be represented in double but nor can it be represented in BigDecimal so you have to apply reasonable rounding to get the expected solution.

double d = 60 / 1.1 * 1.1;
System.out.println("double without rounding: " + d);
System.out.printf("double With rounding %.2f%n", d);

BigDecimal bd = BigDecimal.valueOf(60).divide(BigDecimal.valueOf(1.1), 9, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(1.1));
System.out.println("BigDecimal without rounding: " + bd);
System.out.printf("BigDecimal with rounding %.2f%n", bd);
// or
bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("BigDecimal with rounding: " + bd);

prints

double without rounding: 60.0
double With rounding 60.00
BigDecimal without rounding: 59.9999999995
BigDecimal with rounding 60.00
BigDecimal with rounding: 60.00

Note: double happens to round correctly for these values and gives the right answer. However, pick a different combination and it will be incorrect. e.g. 54.545454545454545 * 1.1 => 60.00000000000001

like image 175
Peter Lawrey Avatar answered Jan 15 '23 16:01

Peter Lawrey


You need to use String constructor instead of double one. 60/1.1 doesn't have String representation, as it is 54.(54).

BigDecimal does not support numbers that cannot be written as a fixed length decimals.

From BigDecimal Javadoc:

In the case of divide, the exact quotient could have an infinitely long decimal expansion; for example, 1 divided by 3. If the quotient has a nonterminating decimal expansion and the operation is specified to return an exact result, an ArithmeticException is thrown. Otherwise, the exact result of the division is returned, as done for other operations.

like image 21
Michal Kordas Avatar answered Jan 15 '23 17:01

Michal Kordas