任何人都可以推荐一个 有效的 法确定是否 BigDecimal 是一个整数值在数学意义上的?

现在我有下列代码:

private boolean isIntegerValue(BigDecimal bd) {
    boolean ret;

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

    return ret;
}

...但是,希望避免的对象创造的开销,如果有必要的。以前我在用 bd.longValueExact() 这将避免制造一个对象如果 BigDecimal 正在利用其紧凑表示国内的,但显然会失败,如果价值是太大,不适合进入一个漫长的。

任何帮助的赞赏。

有帮助吗?

解决方案

根据您BigDecimal值的源/使用它可能会更快,以检查是否规模<= 0第一个。如果是,那么它肯定在数学意义上的整数值。如果是> 0,则它的仍是一个整数值,并将需要更昂贵的测试。

其他提示

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

BigDecimal stripTrailingZeros 不适用于零

所以

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的数目,并检查其余数。当除以1的任何整数。应该始终有一个的0剩余部分。

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

可以使用本(从其他的答案仅仅总结):

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

一种可能性应该被检查,如果 scale() 是零或负面的。在这种情况下的BigDecimal不应该有位小数点后和数应该是一个数学整数如果我理解你的问题是否正确。

更新:如果是积极的,它仍然可能是整数,但是你不能放额外的对象的创造进一步深入检查,在这种情况。一个例子对于这样一种情况是在 stripTrailingZeros() 方法,如果是的话,为什么不试(感谢约阿希姆*为暗示在他的回答).

这是我想出来的最清洁的。

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

这是可以做到的相同方式,有人会检查是否有双重是一个整数,执行%1 == 0。这是它如何寻找一个BigDecimal值。

public static boolean isIntegerValue(BigDecimal bd){
  return bd.remainder(new BigDecimal("1")).compareTo(BigDecimal.ZERO) == 0;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top