使用BigDecimal确定小数位数

Che*_*eng 14 java

我有兴趣拥有以下getNumberOfDecimalPlace功能:

System.out.println("0 = " + Utils.getNumberOfDecimalPlace(0));          // 0
System.out.println("1.0 = " + Utils.getNumberOfDecimalPlace(1.0));      // 0
System.out.println("1.01 = " + Utils.getNumberOfDecimalPlace(1.01));    // 2
System.out.println("1.012 = " + Utils.getNumberOfDecimalPlace(1.012));  // 3
System.out.println("0.01 = " + Utils.getNumberOfDecimalPlace(0.01));    // 2
System.out.println("0.012 = " + Utils.getNumberOfDecimalPlace(0.012));  // 3
Run Code Online (Sandbox Code Playgroud)

我可以getNumberOfDecimalPlace通过使用来了解如何实施BigDecimal

以下代码无法按预期工作:

public static int getNumberOfDecimalPlace(double value) {
    final BigDecimal bigDecimal = new BigDecimal("" + value);
    final String s = bigDecimal.toPlainString();
    System.out.println(s);
    final int index = s.indexOf('.');
    if (index < 0) {
        return 0;
    }
    return s.length() - 1 - index;
}
Run Code Online (Sandbox Code Playgroud)

以下内容打印出来:

0.0
0 = 1
1.0
1.0 = 1
1.01
1.01 = 2
1.012
1.012 = 3
0.01
0.01 = 2
0.012
0.012 = 3
Run Code Online (Sandbox Code Playgroud)

但是,对于情况0,1.0,它不能很好地工作.我期待,结果是"0".但结果却是"0.0"和"1.0".这将返回"1".

Rob*_*ins 33

这段代码:

int getNumberOfDecimalPlaces(BigDecimal bigDecimal) {
    String string = bigDecimal.stripTrailingZeros().toPlainString();
    int index = string.indexOf(".");
    return index < 0 ? 0 : string.length() - index - 1;
}
Run Code Online (Sandbox Code Playgroud)

......通过这些测试:

assertThat(getNumberOfDecimalPlaces(new BigDecimal("0.001")), equalTo(3));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("0.01")), equalTo(2));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("0.1")), equalTo(1));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("1.000")), equalTo(0));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("1.00")), equalTo(0));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("1.0")), equalTo(0));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("1")), equalTo(0));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("10")), equalTo(0));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("10.1")), equalTo(1));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("10.01")), equalTo(2));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("10.001")), equalTo(3));
Run Code Online (Sandbox Code Playgroud)

......如果那确实是你想要的.其他回复是正确的,你必须一直使用BigDecimal而不是double/float.

  • @Robert Atkins**警告**,给我1加"0.0",应为0. (2认同)

Gil*_*ili 33

结合Turismo,Robertuser1777653的答案,我们得到了:

int getNumberOfDecimalPlaces(BigDecimal bigDecimal) {
    return Math.max(0, bigDecimal.stripTrailingZeros().scale());
}
Run Code Online (Sandbox Code Playgroud)
  • stripTrailingZeros()确保不计算尾随零(例如,1.0有0位小数).
  • scale()效率比String.indexOf().
  • 负数scale()表示零小数位.

在那里,你拥有它,两全其美.

  • 当您使用双值构造 BigDecimal 时,这将失败。例如 `new BigDecimal(123.123).stripTrailingZeros().scale()` 将返回 `46`。 (2认同)

小智 6

应该这样做

int getNumberOfDecimalPlace(BigDecimal number) {
    int scale = number.stripTrailingZeros().scale();
    return scale > 0 ? scale : 0;
}
Run Code Online (Sandbox Code Playgroud)


Axe*_*ehl 5

不用转换成String,直接使用scale应该效率更高:

  private int getNumberOfDecimalPlaces(BigDecimal bigDecimal)
  {
    int scale =  bigDecimal.stripTrailingZeros().scale();
    return scale>0?scale:0;
  }
Run Code Online (Sandbox Code Playgroud)

  • 这与 [Gili](/sf/answers/2132979761/) 的答案完全相同...... (2认同)