@ElementCollection (fetch = FetchType.LAZY) @CollectionTable (name = "raw_events_custom", joinColumns = @JoinColumn (name = "raw_event_id")) @MapKeyColumn (name = "field_key", length = 50) @ Столбец (name = "field_val", length = 100) @BatchSize (size = 20) private Map & lt; String, String & gt; customValues = new HashMap & lt; String, String & gt; ();
Это пример того, как настроить карту с контролем над именами столбцов и таблиц и длиной поля.
Из документов Java 5 (Java 8 docs здесь ):
Когда объект MathContext поставляется с настройкой точности 0 (например, MathContext.UNLIMITED), арифметические операции точны, а также арифметические методы, которые не принимают объект MathContext. (Это единственное поведение, которое поддерживалось в версиях до 5.)
. В качестве следствия вычисления точного результата настройка режима округления объекта MathContext с точностью 0 не используется и таким образом, не имеет значения. В случае деления точное частное может иметь бесконечно длинное десятичное разложение; например, 1 делится на 3.
Если фактор имеет бесконечное десятичное расширение и операция указана для возврата точного результата, генерируется исключение ArithmeticException. В противном случае возвращается точный результат деления, как это сделано для других операций.
Чтобы исправить, вам нужно сделать что-то вроде этого:
a.divide(b, 2, RoundingMode.HALF_UP) where 2 is precision and RoundingMode.HALF_UP is rounding mode
Подробнее подробности: http://jaydeepm.wordpress.com/2009/06/04/bigdecimal-and-non-terminating-decimal-expansion-error/
У меня была такая же проблема, потому что моя строка кода была:
txtTotalInvoice.setText(var1.divide(var2).doubleValue() + "");
Я перехожу к этому, читая предыдущий ответ, потому что я не писал десятичную точность:
txtTotalInvoice.setText(var1.divide(var2,4, RoundingMode.HALF_UP).doubleValue() + "");
4 - Десятичная точность
И RoundingMode являются константами Enum, вы можете выбрать любой из этих UP, DOWN, CEILING, FLOOR, HALF_DOWN, HALF_EVEN, HALF_UP
. В этом случае HALF_UP будет иметь следующий результат:
2.4 = 2
2.5 = 3
2.7 = 3
Вы можете проверить информацию RoundingMode
здесь: http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/
Ответа на этот вопрос по BigDecimal throws ArithmeticException
public static void main(String[] args) {
int age = 30;
BigDecimal retireMentFund = new BigDecimal("10000.00");
retireMentFund.setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal yearsInRetirement = new BigDecimal("20.00");
String name = " Dennis";
for ( int i = age; i <=65; i++){
recalculate(retireMentFund,new BigDecimal("0.10"));
}
BigDecimal monthlyPension = retireMentFund.divide(
yearsInRetirement.divide(new BigDecimal("12"), new MathContext(2, RoundingMode.CEILING)), new MathContext(2, RoundingMode.CEILING));
System.out.println(name+ " will have £" + monthlyPension +" per month for retirement");
}
public static void recalculate (BigDecimal fundAmount, BigDecimal rate){
fundAmount.multiply(rate.add(new BigDecimal("1.00")));
}
Добавить объект MathContext в ваш метод разбора и настроить точность и округление. Это должно решить вашу проблему
Потому что вы не указали точность и округление. BigDecimal жалуется, что он может использовать десятичные числа 10, 20, 5000 или бесконечность, и он все равно не сможет дать вам точное представление числа. Таким образом, вместо того, чтобы давать вам неправильный BigDecimal, он просто визжит на вас.
Однако, если вы предоставите RoundingMode и точность, то он сможет конвертировать (например, 1.333333333-to-infinity в нечто например, 1.3333 ... но вам, как программисту, нужно сказать, какую точность вы «довольны».
Вы можете сделать
a.divide(b, MathContext.DECIMAL128)
Вы можете выбрать количество бит, которое вы хотите либо 32,64,128.
Проверьте эту ссылку:
Это вопрос округления результата, решение для меня следующее.
divider.divide(dividend,RoundingMode.HALF_UP);
Для исправления такой проблемы я использовал ниже код
a.divide(b, 2, RoundingMode.HALF_EVEN)
2 - точность. Теперь проблема решена.
precision
; это scale
. См. docs.oracle.com/javase/7/docs/api/java/math/…
– John Manko
23 September 2015 в 16:21
Ваша программа не знает, какую точность использовать десятичные числа, чтобы она выдавала:
java.lang.ArithmeticException: Non-terminating decimal expansion
MathContext precision = new MathContext(int setPrecisionYouWant); // example 2
BigDecimal a = new BigDecimal("1.6",precision);
BigDecimal b = new BigDecimal("9.2",precision);
a.divide(b) // result = 0.17
Это потому, что Bigdecimal не потерян, и если вы разделите 1/3, например, это приведет к повторению десятичной до бесконечности. 0.33333333 ... теоретически, если вы умножаете назад, вы получаете точный результат. Но число бесконечности будет генерировать стек над потоком, и в этом случае исключение запускается.
Мое решение:
try {
result = n1.divide(n2);
} catch (ArithmeticException e){
Log.d("Error bigdecimal", e.toString());
result = (n1.doubleValue() / n2.doubleValue());
};
, в этом случае ваш результат не будет сокращен Rounding
toPlainString
. – Matthew Flaschen 4 January 2011 в 07:50precision
; этоscale
. См. docs.oracle.com/javase/7/docs/api/java/math/… – John Manko 23 September 2015 в 16:20