任何人都可以推荐高效方式来确定BigDecimal
是否是数学意义上的整数值?
目前我有以下代码:
private boolean isIntegerValue(BigDecimal bd) {
boolean ret;
try {
bd.toBigIntegerExact();
ret = true;
} catch (ArithmeticException ex) {
ret = false;
}
return ret;
}
...但是如果有必要,我希望避免对象创建开销。以前我使用bd.longValueExact()
,如果BigDecimal
在内部使用其紧凑表示,则会避免创建对象,但如果值太大而不适合长整数,则显然会失败。
任何帮助表示感谢。
答案 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;
}