Search code examples
javajava-11bigdecimal

DoubleValue of BigDecimal provided wrong output


Using java 11 and Intellij Idea.

I'm in the situation where I get a string of data from an external system and need to reformat this. In the current setup I have this line to extract the value for a sales price:

BigDecimal sellingPrice = BigDecimal.valueOf(Double.parseDouble(somesalesprice));

According to the debugger, the output value of sellingPrice = "4.350000000" Now when I convert this according to this line of code:

long roundedSellingPrice = (long) (sellingPrice.doubleValue() * 100);

the result turns out to be "434". As can be seen, 1 (cent) has magically disappeared. I double-checked the values and this consistent. Out of the 500+ dataset that I'm working with, approx. 40 other records seem to have this problem. For the majority it seems to be going just fine.

I cannot find anything common between these records.

Also, it turns out, the result is always rounded down by 1 cent, never up.

Wonder what this could be?


Solution

  • As weird as it sounds for the data of types Float and Double the precision is not very good. Use BigDecimal for all the calculations. That's the short answer.

    In Addition, when you parse a String to any numerical type you have to deal with exceptions. Sometimes it makes sense and sometimes it doesn't. For the case when you don't care about exception I wrote a utility that parses string to any numeric value and if parsing fails it returns a default value. In case you want your exception messages to be printed into log the same utility optionally may print exception messages into a log. See methods:
    public static java.math.BigDecimalparseStringToBigDecimal(java.lang.CharSequence num, java.math.BigDecimal defaultValue)
    and
    public static java.math.BigDecimal parseStringToBigDecimal(java.lang.CharSequence num, java.math.BigDecimal defaultValue, java.lang.String nullOrEmptyStringErrorMessage, java.lang.String numberFormatErrorMessage)
    Those methods can be pretty useful. The utility is comes with Open Source MgntUtils library written and maintained by me. You can get it as maven artifacts or at Github