Check if BigDecimal is integer value

前端 未结 7 2146
有刺的猬
有刺的猬 2021-02-03 17:36

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

At present I have

相关标签:
7条回答
  • 2021-02-03 17:40

    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.

    0 讨论(0)
  • 2021-02-03 17:42

    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.

    public static boolean isIntegerValue(BigDecimal bd){
      return bd.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0;
    }
    
    0 讨论(0)
  • 2021-02-03 17:44

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

    public boolean isWholeNumber(BigDecimal number) {
        return number.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0;
    }
    
    0 讨论(0)
  • 2021-02-03 17:45

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

    private boolean isIntegerValue(BigDecimal bd) {
      return bd.stripTrailingZeros().scale() <= 0;
    }
    
    0 讨论(0)
  • 2021-02-03 17:51

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

    0 讨论(0)
  • 2021-02-03 17:54

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

    BigDecimal stripTrailingZeros doesn't work for zero

    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.

    So you could do something like this:

    private boolean isIntegerValue(BigDecimal bd) {
      return bd.signum() == 0 || bd.scale() <= 0 || bd.stripTrailingZeros().scale() <= 0;
    }
    
    0 讨论(0)
提交回复
热议问题