views:

1053

answers:

3

Can anyone recommend an efficient way of determining whether a BigDecimal is an integer value in the mathematical sense?

At present I have the following code:

private boolean isIntegerValue(BigDecimal bd) {
    boolean ret;

    try {
        bd.toBigIntegerExact();
        ret = true;
    } catch (ArithmeticException ex) {
        ret = false;
    }

    return ret;
}

... but would like to avoid the object creation overhead if necessary. Previously I was using bd.longValueExact() which would avoid creating an object if the BigDecimal was using its compact representation internally, but obviously would fail if the value was too big to fit into a long.

Any help appreciated.

+4  A: 

Depending on the source/usage of your BigDecimal values it might be faster to check if the scale <= 0 first. If it is, then it's definitely an integer value in the mathematical sense. If it is >0, then it could still be an integer value and the more expensive test would be needed.

Joachim Sauer
Thanks - Don't know why I didn't think of that, and it's a good optimisation for as this method as I expect the check to pass 99% of the time.
Adamski
+2  A: 

One possiblity should be to check if scale() is zero or negative. In that case the BigDecimal should have no digits after the decimal point and the number should be a mathematical integer if I understand your question correctly.

Update: If positive, it could still be an integer, but you cannot spare extra object creations for further in-depth checks in that case. An example for such a case is given at the stripTrailingZeros() method javadoc (thanks Joachim for the hint in his answer).

Kosi2801
Thanks - Useful info.
Adamski
A: 

You can use this (just summarizing from other answers):

private boolean isIntegerValue(BigDecimal bd) {
  return bd.stripTrailingZeros().scale() <= 0;
}
emisch