Java 检查 BigDecimal 是否为整数值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1078953/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:15:25  来源:igfitidea点击:

Check if BigDecimal is integer value

javabigdecimal

提问by Adamski

Can anyone recommend an efficientway of determining whether a BigDecimalis an integer value in the mathematical sense?

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

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 BigDecimalwas using its compact representation internally, but obviously would fail if the value was too big to fit into a long.

...但希望在必要时避免对象创建开销。以前我使用bd.longValueExact()which 将避免创建一个对象,如果BigDecimal它在内部使用它的紧凑表示,但如果值太大而无法放入 long 中,显然会失败。

Any help appreciated.

任何帮助表示赞赏。

采纳答案by Joachim Sauer

Depending on the source/usage of your BigDecimalvalues 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 couldstill be an integer value and the more expensive test would be needed.

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

回答by Kosi2801

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.

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

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).

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

回答by emisch

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

您可以使用它(仅从其他答案中总结):

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

回答by tobi

EDIT: As of Java 8, stripTrailingZeroes() now accounts for zero

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

BigDecimal stripTrailingZeros doesn't work for zero

BigDecimal stripTrailingZeros 对零不起作用

So

所以

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

Is perfectly fine now.

现在完全好了。



If you use the scale()and stripTrailingZeros()solution mentioned in some of the answers you should pay attention to zero. Zero always is an integer no matter what scale it has, and stripTrailingZeros()does not alter the scale of a zero BigDecimal.

如果您使用某些答案中提到的scale()stripTrailingZeros()解决方案,您应该注意零。零总是一个整数,无论​​它有什么标度,并且stripTrailingZeros()不会改变零 BigDecimal 的标度。

So you could do something like this:

所以你可以做这样的事情:

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

回答by Ian

This is the cleanest I've come up with.

这是我想到的最干净的。

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

回答by StPatrick

Divide the number by 1 and check for a remainder. Any whole number should always have a remainder of 0 when divided by 1.

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

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

回答by Scott Armstrong

This can be done the same way that someone would check if a double is an integer, performing % 1 == 0. This is how it would look for a BigDecimal value.

这可以通过与某人检查 double 是否为整数相同的方式来完成,执行 % 1 == 0。这就是它查找 BigDecimal 值的方式。

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