0

In order to avoid possible loss of precision in Java operation on Double objects i.e.:

Double totalDouble = new Double(1590.0);
Double taxesDouble = new Double(141.11);
Double totalwithTaxes = Double.sum(totalDouble,taxesDouble);
//KO: 1731.1100000000001
System.out.println(totalwithTaxes); // 1731.1100000000001

I wrote this code, where totalDouble and taxesDouble could be also null:

Double totalDouble = myObject.getTotalDouble();
Double taxesDouble = myObject.getTaxesDouble();
BigDecimal totalBigDecimalNotNull = (totalDouble==null) ? BigDecimal.valueOf(0d):BigDecimal.valueOf(totalDouble);
BigDecimal taxesBigDecimalNotNull = (taxesDouble==null) ? BigDecimal.valueOf(0d):BigDecimal.valueOf(taxesDouble);
BigDecimal totalWithTaxesBigDecimal = totalBigDecimalNotNull.add(taxesBigDecimalNotNull);
System.out.println(totalWithTaxesBigDecimal);

Is there a better way (also with third part libraries i.e. guava, etc) to initialize BigDecimal in this cases (zero if Double is null and Double value otherwise)?

user6904265
  • 1,938
  • 1
  • 16
  • 21

2 Answers2

1

Not really. That is to say, you're still going to need to make a decision based on whether or not the value is null, but you can do it cleaner if you use the Optional pattern.

You can change your getTotalDouble and getTaxesDouble returns to Optional<Double> instead to mititgate having to do the ternary...

public Optional<Double> getTotalDouble() {
   return Optional.ofNullable(totalDouble);
}

public Optional<Double> getTaxesDouble() {
   return Optional.ofNullable(taxesDouble);
}

...then, you can use the conditional evaluation provided by Optional itself to evaluate and return a default value.

BigDecimal totalBigDecimalNotNull =
           BigDecimal.valueOf(myObject.getTotalDouble().orElse(0d));

A simplification would be to return Optional<BigDecimal> instead, as opposed to transforming the value that you want in this fashion.

As an addendum, be careful when talking about precision. There is standing advice to use either int or long instead to ensure you don't lose any coin precision.

Community
  • 1
  • 1
Makoto
  • 104,088
  • 27
  • 192
  • 230
  • thanks for the hint about the "Optional" usage, I think I'll use it in the future. For the use of int or long for money representation, unfortunately I can't change this choice. I would have liked to use integer (and count the cent) or use BigDecimal, but I work with e-commerce framework and it uses double.. – user6904265 Nov 18 '16 at 21:12
1

Whether you use Optional or not I recommend creating a static helper method so that you don't have to repeat yourself. e.g.:

public static BigDecimal bigDecimalValueOfOrZero(Double val) {
    return val == null ? BigDecimal.ZERO : BigDecimal.valueOf(val);
}
mfulton26
  • 29,956
  • 6
  • 64
  • 88