如何检查BigDecimal的位数?

时间:2016-03-04 09:38:53

标签: java

要求是检查数字位数是否小于7位数,在这种情况下插入数据库,否则不行。我尝试了以下解决方案:

第一个解决方案:

public static void checkNoOfDigitVal(BigDecimal bigDecVal) {
    BigInteger digits = bigDecVal.toBigInteger();
    BigInteger ten = BigInteger.valueOf(10);
    int count = 0;
    do {
        digits = digits.divide(ten);
        count++;
    } while (!digits.equals(BigInteger.ZERO));
    System.out.println("Number of digits : " + count);
}

有时候第一个解决方案工作正常,但有时候while循环中的条件不满足,并且不断增加计数,导致无穷无尽的计数。

第二个解决方案:

public static void checkNoOfDigitsVal(BigDecimal bigDecVal) {
    String string = bigDecVal.toString();
    String[] splitedString = string.split("\\.");
    String[] newVal = splitedString[0].split("");
    int a = newVal.length - 1;
    if (a <= 6) {
        System.out.println("correct size insert into DB: " + a);
    } else {
        System.out.println("Incorrect size insert cancel: " + a);
    }
}

例如,如果值为999999.9999,则第二个解决方案将返回newVal.length = 6

请建议一个更好的解决方案来检查大小数位数,以便最大限度地减少循环开销。

4 个答案:

答案 0 :(得分:17)

您可以使用以下方式轻松获得:

static int integerDigits(BigDecimal n) {
    n = n.stripTrailingZeros();
    return n.precision() - n.scale();
}

精度是总位数,刻度是小数点右边的数量,所以差异是小数点 left 的数量

编辑有必要删除任何尾随的零以获得正确的结果,例如0.000

编辑2 或者(和@AdrianShum一样),因为尾随零的问题只能用0.00...表示,你可以使用:

static int integerDigits(BigDecimal n) {
    return n.signum() == 0 ? 1 : n.precision() - n.scale();
}

http://ideone.com/uI6iMG

的现场演示

答案 1 :(得分:1)

  1. 如果要忽略点(“。”)并计数。然后试试这个:
<Grid Margin="0,0,0,0">
    <local:DockPanelTop />
    <local:DockPanelBtm />

    <Grid Margin="5,45,5,25" x:Name="MainGrid" x:FieldModifier="public">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200" MaxWidth="400" MinWidth="0" x:Name="MainMenu" x:FieldModifier="public" />
            <ColumnDefinition Width="5" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <Rectangle Grid.Column="0" Fill="AliceBlue" />
        <GridSplitter HorizontalAlignment="Stretch" Background="#FFFF7E7E" Grid.Column="1" />
        <Rectangle Grid.Column="2" Fill="AntiqueWhite" />

        【"View this into ColumnDefinition(2)"<local:TreeView />】

    </Grid>

答案 2 :(得分:0)

你的第二个解决方案很接近,但它并不是那么复杂:

public static void checkNoOfDigitsVal(BigDecimal bigDecVal) {
    String str = bigDecVal.toString();
    int wholeNumberLength = str.split("\\.")[0].length();
    if (wholeNumberLength <= 6) {
        System.out.println("correct size insert into DB: " + wholeNumberLength);
    } else {
        System.out.println("Incorrect size insert cancel: " + wholeNumberLength);
    }
}

Live Example

我假设您的999999.999示例应该导致wholeNumberLnegth 6并因此被插入数据库中(问题不清楚)。

答案 3 :(得分:0)

因为当前答案还不够强大,IMO,这是我的解决方案。 此方法会将BigDecimal缩放到给定的长度,但仅缩放小数部分。如果整数部分将被缩放,它将抛出一个异常。对于我的用例,这就是我想要的。根据自己的喜好进行调整。

public static BigDecimal scaleBigDecimalToLength(BigDecimal bigDecimal, int length) throws NumbersUtilException {
  int digitCount = bigDecimal.toString().replaceAll("[.,]", "").length();
  if (digitCount > length) {
      int scale = bigDecimal.scale();
      int newScale = length - (digitCount - scale);
      if (scale > 0 && newScale >= 0) {
          bigDecimal = bigDecimal
                  .setScale(length - (digitCount - scale), RoundingMode.HALF_UP);
      } else {
          throw new NumbersUtilException(
                  String.format("Cannot scale %s to a length of %s", bigDecimal, length));
    }
  }
  return bigDecimal;
}

scaleBigDecimalToLength(BigDecimal.valueOf(0.0000012345600000), 8) 输出:0.0000012