Как считать цифры в BigDecimal? - PullRequest
       32

Как считать цифры в BigDecimal?

1 голос
/ 01 октября 2019

Я имею дело с BigDecimal в Java, и мне нужно сделать 2 проверки с полями BigDecimal в моем DTO:

  1. Количество цифр полной части (до точки) <15</li>
  2. Общее количество цифр <32, включая шкалу (нули после точки) </li>

Как лучше всего это реализовать? Я крайне не хочу toBigInteger().toString() и .toString()

1 Ответ

1 голос
/ 01 октября 2019

Я думаю, что это сработает.

      BigDecimal d = new BigDecimal("921229392299229.2922929292920000");
      int fractionCount = d.scale();
      System.out.println(fractionCount);
      int wholeCount = (int) (Math.ceil(Math.log10(d.longValue())));
      System.out.println(wholeCount);

Я провел некоторое тестирование вышеупомянутого метода, используя indexOf и вычитая lengths of strings. Вышеуказанное выглядит значительно быстрее , если моя методология тестирования разумна. Вот как я это проверял.

      Random r = new Random(29);
      int nRuns = 1_000_000;
      // create a list of 1 million BigDecimals 

      List<BigDecimal> testData = new ArrayList<>();
      for (int j = 0; j < nRuns; j++) {

         String wholePart = r.ints(r.nextInt(15) + 1, 0, 10).mapToObj(
               String::valueOf).collect(Collectors.joining());

         String fractionalPart = r.ints(r.nextInt(31) + 1, 0, 10).mapToObj(
               String::valueOf).collect(Collectors.joining());

         BigDecimal d = new BigDecimal(wholePart + "." + fractionalPart);
         testData.add(d);
      }

      long start = System.nanoTime();
      // Using math
      for (BigDecimal d : testData) {
         int fractionCount = d.scale();
         int wholeCount = (int) (Math.ceil(Math.log10(d.longValue())));
      }

      long time = System.nanoTime() - start;
      System.out.println(time / 1_000_000.);

      start = System.nanoTime();
      //Using strings
      for (BigDecimal d : testData) {
         String sd = d.toPlainString();
         int n = sd.indexOf(".");
         int m = sd.length() - n - 1;
      }

      time = System.nanoTime() - start;
      System.out.println(time / 1_000_000.);
   }
...