Remove the MathContext
:
public class Teste {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
BigDecimal valorInicial = new BigDecimal("8410");
BigDecimal contanteDivisor = new BigDecimal("100");
BigDecimal resultDivisao = valorInicial.divide(contanteDivisor);
BigDecimal resultado = resultDivisao.multiply(new BigDecimal("4.50"));
System.out.println("Resultado: " + resultado);
}
}
When adding new MathContext(2, RoundingMode.HALF_EVEN)
on the call of BigDecimal
, you are telling it to round the division value to the nearest number by considering up to two digits of accuracy.
With that, when sharing 8410 for 100 according to the excerpt of your code below:
BigDecimal valorInicial = new BigDecimal("8410");
BigDecimal contanteDivisor = new BigDecimal("100");
BigDecimal resultDivisao = valorInicial.divide(contanteDivisor, new MathContext(2, RoundingMode.HALF_EVEN));
resultDivisao
should be 84.10, but with rounding using an accuracy of only two digits the result is 84.
See on ideone the difference between the quotients, with and without rounding.
In the next line,
BigDecimal resultado = resultDivisao.multiply(new BigDecimal("4.50"));
You are multiplying in truth 84 for 4.5, resulting in us 378 that your code is displaying, and not in the expected result(84.10 * 4.50 = 378.45);
It is important to note that if the intention of the code was to limit the number of decimal places of the result of the division, the method should be used setScale
, because we are talking about scale (digits after comma) and not precision (significant digits).
For this, you can adapt the division line as below:
BigDecimal resultDivisao = valorInicial.divide(contanteDivisor)
.setScale(2, RoundingMode.HALF_EVEN);
When the result of the split may be an inaccurate number it is necessary to work also with an accuracy to avoid a ArithmeticException
. Scale adjustment can be done after splitting:
BigDecimal valorInicial = new BigDecimal("8411");
BigDecimal contanteDivisor = new BigDecimal("101");
BigDecimal resultDivisao = valorInicial
.divide(contanteDivisor, new MathContext(10, RoundingMode.HALF_EVEN))
.setScale(2, RoundingMode.HALF_EVEN);
In this case the result of the 8411 for 101 with 10 digit accuracy is 83.27722772. After the scale adjustment the final result is 83.28.
That is, accuracy sets the number of digits to be computed while the scale adjusts the number of decimals.
See the corrected code running on IDEONE.
References:
Documentation: Roundingmode
Documentation: Bigdecimal.setScale
Bigdecimal setScale and round
Thank you very much !
– AmandaRJ