java 如何检查 BigDecimal 的位数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35792590/
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-11-03 00:36:04  来源:igfitidea点击:

How to check number of digits from BigDecimal?

java

提问by Harleen

The requirement is to check if the number of digits is less than 7 digits in that case insert in DB else don't. I have tried the following solutions:

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

First solution:

第一个解决方案:

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);
}

First solution works fine sometimes but sometimes the condition in while loop is not satisfied and it keeps on increasing the count number leading to endless count.

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

Second solution:

第二种解决方案:

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);
    }
}

For example, if the value is 999999.9999, the second solution will return newVal.length = 6.

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

Please suggest a better solution to check the number of digits for big decimal where looping overhead can be minimized.

请提出一个更好的解决方案来检查大十进制的位数,其中循环开销可以最小化。

回答by Alnitak

You can get it trivially using:

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

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

The precision is the total number of digits, and the scale is how many of those are to the right of the decimal point, so the difference is how many are to the leftof the decimal point.

精度是总位数,小数位数是小数点右边有多少位,所以差就是小数点左边有多少位。

EDITit's necessary to remove any trailing zeros to get a correct result for e.g. 0.000

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

EDIT 2alternatively (and acks to @AdrianShum), since the problem with trailing zeroes only manifests itself with 0.00...you could use:

或者编辑 2(并确认@AdrianShum),因为尾随零的问题只会在0.00...您可以使用时表现出来:

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

Live demo at http://ideone.com/uI6iMG

现场演示http://ideone.com/uI6iMG

回答by T.J. Crowder

There's a muchbetter solution in Alnitak's answer, posted just after mine (but which I've only seen now). I guess I'll leave this since a couple of people have found it useful, but if I needed to do this, I'd use their approach, not the approach below.

有一个很大的更好的解决方案参宿一的答案,只是我的(但我只看到现在)后公布。我想我会离开这个,因为有几个人发现它很有用,但如果我需要这样做,我会使用他们的方法,而不是下面的方法。



Your second solution is close, but it doesn't have to be quite that complicated:

您的第二个解决方案很接近,但不必那么复杂:

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

现场示例

I'm assuming that your 999999.999example should result in wholeNumberLnegthof 6and therefore be inserted in the DB (the question is unclear about that).

我假设你的999999.999例子应该导致wholeNumberLnegthof6并因此被插入到数据库中(这个问题不清楚)。

回答by Dormouse

Because the current answers are not robust enough IMO, Here's my solution. This method will scale a BigDecimalto the given length, but only scales the fractional part. It will throw an Exception if the integer part will be scaled. For my use case this is what I want. Tweak it to your liking.

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

public static BigDecimal scaleBigDecimalToLength(BigDecimal bigDecimal, int length) throws NumbersUtilException {
  int digitCount = bigDecimal.toPlainString().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)Output: 0.0000012

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

回答by JavaTech

  1. If you want to ignore the Dot (".") and count. then try this :
  1. 如果你想忽略点(“.”)并计数。然后试试这个:
        int count = 0;
        BigDecimal bigDecimal = new BigDecimal("123.1000");

        String[] split = bigDecimal.toString()
                .split("\.");

        for (String element : split) {
            count = count + element.length();
        }

        System.out.println("Total digits are " + count);