ArithmeticException: "Нескончаемое десятичное представление; нет точного десятичного результата"
Почему следующий код вызывает указанное ниже исключение?
BigDecimal a = new BigDecimal("1.6");
BigDecimal b = new BigDecimal("9.2");
a.divide(b); // приводит к следующему исключению.
Исключение:
java.lang.ArithmeticException: Нерегулярное десятичное представление; нет точного представимого десятичного результата.
5 ответ(ов)
Чтобы решить такую проблему, я использовал следующий код:
a.divide(b, 2, RoundingMode.HALF_EVEN)
Где 2
— это масштаб. Теперь проблема должна быть решена.
Это проблема округления результата. Решение для меня следующее:
divider.divide(dividend, RoundingMode.HALF_UP);
Проблема заключается в том, что вы не указываете точность и режим округления. BigDecimal «жалуется», потому что может использовать 10, 20, 5000 или даже бесконечное количество десятичных знаков, и при этом он всё равно не сможет предоставить вам точное представление числа. Вместо того чтобы возвращать некорректный BigDecimal, он просто сообщает вам об этом.
Однако, если вы укажете режим округления и точность, тогда он сможет преобразовать, например, 1.333333333 до бесконечности в что-то вроде 1.3333... Но вам, как программисту, нужно будет сообщить ему, с какой точностью вы «согласны».
Я столкнулся с такой же проблемой, и вот мой исходный код:
txtTotalInvoice.setText(var1.divide(var2).doubleValue() + "");
Я изменил его на следующее, опираясь на предыдущий ответ, так как не учитывал десятичную точность:
txtTotalInvoice.setText(var1.divide(var2, 4, RoundingMode.HALF_UP).doubleValue() + "");
Здесь 4
— это десятичная точность.
Кроме того, RoundingMode
является перечислением, и вы можете выбрать любой из следующих режимов округления:
UP, DOWN, CEILING, FLOOR, HALF_DOWN, HALF_EVEN, HALF_UP
.
В данном случае HALF_UP
будет давать такие результаты:
2.4 = 2
2.5 = 3
2.7 = 3
Вы можете ознакомиться с информацией о RoundingMode
здесь: JavaBeat - Precise Rounding of Decimals Using RoundingMode Enumeration.
Ваше приложение не знает, какую точность использовать для дробных чисел, поэтому вы получаете исключение:
java.lang.ArithmeticException: Non-terminating decimal expansion
Решение, чтобы избежать исключения:
Вы можете задать необходимую точность для вычислений, используя класс MathContext
в Java. Пример:
MathContext precision = new MathContext(2); // например, 2
BigDecimal a = new BigDecimal("1.6", precision);
BigDecimal b = new BigDecimal("9.2", precision);
BigDecimal result = a.divide(b); // результат = 0.17
Используя MathContext
, вы можете контролировать количество знаков после запятой, что позволяет избежать проблемы с бесконечными десятичными дробями.
Инициализация ArrayList в одну строчку
Что значит "Не удалось найти или загрузить основной класс"?
Как установить Java 8 на Mac
Почему в RecyclerView отсутствует onItemClickListener()?
Что значит 'synchronized'?