¿Por qué si uso BigDecimal
en este caso, no obtengo el resultado esperado?
double value1 = 5.68;
double value2 = 2.45;
System.out.println(BigDecimal.valueOf(value1 + value2));
SALIDA:
8.129999999999999
ESPERADO:
8.13
¿Por qué si uso BigDecimal
en este caso, no obtengo el resultado esperado?
double value1 = 5.68;
double value2 = 2.45;
System.out.println(BigDecimal.valueOf(value1 + value2));
8.129999999999999
8.13
Lo que pasa es que estas haciendo la suma de los double
no de los BigDecimal
Te recomiendo esto en su lugar
double value1 = 5.68;
double value2 = 2.45;
System.out.println(BigDecimal.valueOf(value1).add(BigDecimal.valueOf(value2)));
De esta forma cada número es convertido primero en un BigDecimal
antes de realizar la suma.
Como el operador +
no funciona con BigDecimal
se debe usar el método .add()
en su lugar
Cuando uses BigDecimal
, conviene usar siempre los constructores y métodos que no usen el tipo double
, ya que, como supongo ya sabes, el tipo double
no tiene representaciones exactas para muchos números que tienen representación exacta en base 10.
Para tu ejemplo, podrías usar:
/* Usa valueOf(long valorSinEscalar, int escala) */
long value1 = 568;
long value2 = 245;
System.out.println(BigDecimal.valueOf(value1 + value2, 2));
o tal vez:
/* Usa el constructor BigDecimal(long valorSinEscalar, int escala) */
BigDecimal value1 = BigDecimal.valueOf(568, 2);
BigDecimal value2 = BigDecimal.valueOf(245, 2);
System.out.println(value1.add(value2));
o este otro:
/* Usa el constructor BigDecimal(String valor) */
BigDecimal value1 = new BigDecimal("5.68");
BigDecimal value2 = new BigDecimal("2.45");
System.out.println(value1.add(value2));
Nótese que hay una versión de estos constructores con un parámetro adicional MathContext
, que permite seleccionar el modo de redondeo.
Puesto que la pregunta es sobre redondeo utilizando BigDecimal
, solo debes usar el método BigDecimal#setScale(int, RoundingMode)
:
System.out.println(BigDecimal.valueOf(value1 + value2).setScale(2, RoundingMode.HALF_EVEN));
El resultado será:
8.13
Puedes ver un ejemplo de esto corriendo en ideone.
Obviamente, no significa que esta es la forma de proceder con las operaciones decimales. Lo mejor sería seguir el ejemplo brindado en la respuesta de @ninjalj, donde si vas a utilizar números decimales, inicialices BigDecimal
utilizando cadenas en lugar de double
:
/* Usa el constructor BigDecimal(String valor) */
BigDecimal value1 = new BigDecimal("5.68");
BigDecimal value2 = new BigDecimal("2.45");
System.out.println(value1.add(value2));
De todas maneras, si las operaciones de arriba deben tener un número fijo de decimales, utiliza setScale
.