Even using BigDecimal I have problems with rounding

13

Why should I use BigDecimal in this case, I do not get the expected result?

double value1 = 5.68;
double value2 = 2.45;
System.out.println(BigDecimal.valueOf(value1 + value2));

DEPARTURE:

8.129999999999999

EXPECTED:

8.13
    
asked by Jordi Castilla 16.12.2015 в 16:20
source

3 answers

15

What happens is that you are making the sum of double not of BigDecimal

I recommend this instead

double value1 = 5.68;
double value2 = 2.45;
System.out.println(BigDecimal.valueOf(value1).add(BigDecimal.valueOf(value2)));

In this way each number is first converted into a BigDecimal before the addition is made.

Since the + operator does not work with BigDecimal , the .add() method should be used instead

    
answered by 16.12.2015 / 16:24
source
4

When you use BigDecimal , you should always use the constructors and methods that do not use the type double , since, as I assume you know, the type double does not have exact representations for many numbers that have exact representation in base 10.

For your example, you could use:

/* Usa valueOf(long valorSinEscalar, int escala) */
long value1 = 568;
long value2 = 245;
System.out.println(BigDecimal.valueOf(value1 + value2, 2));

or maybe:

/* 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));

or this one:

/* Usa el constructor BigDecimal(String valor) */
BigDecimal value1 = new BigDecimal("5.68");
BigDecimal value2 = new BigDecimal("2.45");
System.out.println(value1.add(value2));

Note that there is a version of these constructors with an additional parameter MathContext , which allows you to select the rounding mode.

    
answered by 16.12.2015 в 19:54
1

Since the question is about rounding using BigDecimal , you should only use the method BigDecimal#setScale(int, RoundingMode) :

System.out.println(BigDecimal.valueOf(value1 + value2).setScale(2, RoundingMode.HALF_EVEN));

The result will be:

8.13

You can see an example of this running on ideone .

Obviously, it does not mean that this is the way to proceed with decimal operations. It would be best to follow the example given in the answer of @ninjalj , where if you are going to use decimal numbers, initial BigDecimal using strings instead of 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));

However, if the above operations must have a fixed number of decimals, use setScale .

    
answered by 17.02.2016 в 00:23