Максимальная точность ниже неограниченной?

Я использую BigDecimal для выполнения некоторых вычислений. Недавно я столкнулся с:

java.lang.ArithmeticException: 
Non-terminating decimal expansion; no exact representable decimal result.

Ответ на эту проблему был опубликован здесь: ArithmeticException: " Неограничивающее десятичное расширение; нет точного представляемого десятичного результата "

Это означает, что существует некоторое деление с неограниченными десятичными знаками, поэтому BigDecimal говорит мне, что он не может точно вычислить результат. Чтобы этого избежать, я должен позвонить BigDecimal.setScale(SOMETHING, ROUNDING_MODE);

EDIT:

Теперь проблема заключается в том, чтобы установить SOMETHING в максимально возможное значение. Я мог бы использовать MathContext с точностью ниже UNLIMITED (MathContext(precision)), но та же проблема возникает там. Там должно быть значение ниже   MathContext.UNLIMITED...

Кто-нибудь знает, как это сделать?

Переместил мой второй вопрос на: Почему нет метода BigDecimal.setPrecision()?

Спасибо!

Оливер

Ответ 1

Первый вопрос: Нет такой вещи, как BigDecimal.UNLIMITED. Это не имеет никакого смысла. Что меньше, чем бесконечность? Поскольку docs явно не упоминает MathContext по умолчанию для BigDecimal, я должен предположим, что это MathContext.UNLIMITED. Увидев, что у вас есть повторяющееся десятичное число, BigDecimal не может его удерживать даже с неограниченной точностью. Вместо этого вам нужно произвольно выбрать значение (скажем, 100 или 1000 - я понятия не имею, для чего вы используете эти цифры). Если вы только заботитесь о первом, скажем, 15 десятичных разрядах, вы никогда не должны иметь ошибку округления, если вы отслеживаете первый, скажем, 100.

Второй вопрос: задайте ему отдельный вопрос.

Ответ 2

BigDecimal.setScale принимает в качестве аргумента int. Таким образом, максимально возможный масштаб

2,147,483,647

Но, как упоминалось выше, вы не должны использовать такие огромные масштабы. Число, которое вы вычисляете, будет потреблять много памяти без какой-либо полезной цели. Вычисление числа может занять очень много времени.

Ответ 3

Один обходной путь связанного ответа с использованием unlimited precision arithmetic (MathContext.UNLIMITED):

BigDecimal a = new BigDecimal("1.6");
BigDecimal b = new BigDecimal("9.2");
a = new BigDecimal(a.doubleValue()/b.doubleValue(), MathContext.UNLIMITED);
System.out.println("Result => " + a);

ВЫХОД: На моем 64-битном OSX 10.6.8 с java "1.6.0_51"

Result => 0.1739130434782608924937363781282329000532627105712890625

PS: Обратите внимание, что это все еще обходное решение, так как я преобразовываю объект BigDecimal в double для деления и, таким образом, ограничивая возможность деления чисел больше двух раз.