检查BigDecimal是否为整数值

时间:2009-07-03 11:28:16

标签: java bigdecimal

任何人都可以推荐高效方式来确定BigDecimal是否是数学意义上的整数值?

目前我有以下代码:

private boolean isIntegerValue(BigDecimal bd) {
    boolean ret;

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

    return ret;
}

...但是如果有必要,我希望避免对象创建开销。以前我使用bd.longValueExact(),如果BigDecimal在内部使用其紧凑表示,则会避免创建对象,但如果值太大而不适合长整数,则显然会失败。

任何帮助表示感谢。

7 个答案:

答案 0 :(得分:65)

编辑:从Java 8开始,stripTrailingZeroes()现在占零

BigDecimal stripTrailingZeros doesn't work for zero

所以

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

现在完全没问题。


如果您使用某些答案中提到的scale()stripTrailingZeros()解决方案,则应注意零。零总是一个整数,无论​​它具有什么规模,stripTrailingZeros()都不会改变零BigDecimal的范围。

所以你可以这样做:

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

答案 1 :(得分:13)

根据BigDecimal值的来源/用法,可能会更快检查比例是否为&lt; = 0。如果是,则它绝对是数学意义上的整数值。如果它> 0,那么它可能仍然是一个整数值,并且需要更昂贵的测试。

答案 2 :(得分:5)

将数字除以1并检查余数。除以1时,任何整数应始终具有0的余数。

public boolean isWholeNumber(BigDecimal number) {
    return number.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0;
}

答案 3 :(得分:4)

你可以使用它(只是总结其他答案):

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

答案 4 :(得分:2)

一种可能性应该是检查scale()是零还是否定。在这种情况下,BigDecimal在小数点后应该没有数字,如果我正确理解你的问题,数字应该是一个数学整数。

更新:如果是肯定的,它仍然可以是一个整数,但在这种情况下,您无法为额外的对象创建进行进一步的深入检查。 stripTrailingZeros()方法javadoc给出了这种情况的一个例子(感谢Joachim在他的回答中提示)。

答案 5 :(得分:1)

这可以像某人检查double是否为整数一样,执行%1 == 0.这就是它查找BigDecimal值的方式。

public static boolean isIntegerValue(BigDecimal bd){
  return bd.remainder(new BigDecimal("1")).compareTo(BigDecimal.ZERO) == 0;
}

答案 6 :(得分:0)

这是我提出的最干净的。

public static boolean isWhole(BigDecimal bigDecimal) {
    return bigDecimal.setScale(0, RoundingMode.HALF_UP).compareTo(bigDecimal) == 0;
}