Search code examples
javabigdecimal

Exception in thread "main" java.lang.ArithmeticException: Rounding necessary


when i try to get the longValueExact() :

BigDecimal bigDecimal = new BigDecimal(432.900).divide(new BigDecimal(1), 2, RoundingMode.FLOOR);
System.out.println(bigDecimal.longValueExact());

Exception in thread "main" java.lang.ArithmeticException: Rounding necessary
    at java.math.BigDecimal.commonNeedIncrement(BigDecimal.java:4151)
    at java.math.BigDecimal.needIncrement(BigDecimal.java:4207)
    at java.math.BigDecimal.divideAndRound(BigDecimal.java:4115)
    at java.math.BigDecimal.setScale(BigDecimal.java:2455)
    at java.math.BigDecimal.longValueExact(BigDecimal.java:3093)
    at com.tessi.bmd.specific.actil.utils.ActilUtils.main(ActilUtils.java:1281)

Solution

  • new BigDecimal(432.900)

    This is a bad idea. 432.900 is a double literal and is therefore highly unlikely to actually represent 432.900. You're using BigDecimal, so presumably you know that there are only at most 2^64 numbers in existence that are exactly representable by a double. 432.900 is not one of them. Do not use this constructor - it has warnings all over it. Use new BigDecimal("432.9").

    .divide(new BigDecimal(1),

    Okay, divide by 1, not going to do anything. Also, use BigDecimal.ONE for this.

    The value is still 432.899999999999434 or whatnot.

    System.out.println(bigDecimal.longValueExact());

    Of course that doesn't work - a long value can only hold integral values, and 432.9 (or something close to that) isn't.

    Are you perhaps thinking that 432.900 is just a way of writing 432900 that is more readable to humans from certain locales where . is used as thousands separator?

    . is the decimals separator. 432.900 is a double literal that represents the nearest representable double to the number 432 + 9/10ths. If that's your intend, remove the . - if you want to create some horizontal space for the yes, use _ which is legal in number literals and meaningless.

    If that's not your problem and you really want 432.9 as an exact long - I guess, go back to square one and start learning java. Soon (as in, within a day or two, no doubt) you'll hit the part of the tutorial that explains the primitive data types. Pay extra attention to this section.