How to check number of digits from BigDecimal?

Because the current answers are not robust enough IMO, Here's my solution. This method will scale a BigDecimal to 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.

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


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 left of the decimal point.

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

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

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

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


There's a much better 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.999 example should result in wholeNumberLnegth of 6 and therefore be inserted in the DB (the question is unclear about that).

Tags:

Java