BigDecimal и MathContext

Может кто-нибудь объяснить, почему у этих двух разные результаты?

BigDecimal bd1 = new BigDecimal(1234.5678)
    .divide(
        new BigDecimal(1.19),
        4,
        RoundingMode.CEILING
    );
BigDecimal bd2 = new BigDecimal(1234.5678)
    .divide(
        new BigDecimal(1.19),
        new MathContext(4, RoundingMode.CEILING)
    );

Результат:

bd1: 1037.4520
bd2: 1038

Я так понимаю, MCVE, который я собрал для вас, демонстрирует проблему?

Michael 10.12.2018 11:55

Вы усугубили пример. Не используйте двойные литералы для конструкторов BigDecimal, если можете этого избежать. Точность с плавающей запятой делает пример меньше понятным. 1234.5678 не будет 1234.5678.

Michael 10.12.2018 11:58

@ Майкл В том-то и дело. Мой реальный пример похож на нечто подобное. У меня что-то вроде 2074523.35687 в качестве ввода

tzortzik 10.12.2018 12:01

Затем используйте строку

Michael 10.12.2018 12:01
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
4
230
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Потому что в MathContext(4, RoundingMode.CEILING) 4 - это точность, а в .divide(new BigDecimal(1.19), 4, RoundingMode.CEILING); 4 - это масштаб. Вы можете увидеть разницу между "точностью" и "масштабом" здесь

One important point that is alluded to but not directly addressed is the difference between "precision" and "scale" and how they are used in the two statements. "precision" is the total number of significant digits in a number. "scale" is the number of digits to the right of the decimal point.

Итак, если вы измените второй на

final BigDecimal bd2 = new BigDecimal(1234.5678)
        .divide(
                new BigDecimal(1.19),
                new MathContext(8, RoundingMode.CEILING)
        );

У вас такие же результаты:

1037.4520
1037.4520

Другие вопросы по теме