BigDecimal - MathContext.DECIMAL64 против MathContext.DECIMAL128 - PullRequest
0 голосов
/ 09 мая 2018

Я имею дело с разделением денежных величин. В настоящее время я использую MathContext.DECIMAL128 в качестве второго параметра BigDecimal.divide(). Должен ли я использовать MathContext.DECIMAL128 или MathContext.DECIMAL64?

1 Ответ

0 голосов
/ 09 мая 2018

Разница между десятичной32, десятичной64 и десятичной128 составляет (от https://bloomberg.github.io/comdb2/decimals.html):

decimal32 поддерживает показатели в диапазоне от -95 до +96; Имеет 7 цифр (т. е. 0,000000-9,999999).

Диапазон чисел, представляемых этим форматом, составляет от + -0,000000x10−95 до + -9,99999x10 + 96

decimal64 поддерживает показатели в диапазоне от -383 до +384; Имеет 16 цифр (т. е. 0,000000000000000-9,9999999999999999). Диапазон чисел от + -0,000000000000000x10−383 до + -9,9999999999999999x10 + 384

decimal128 поддерживает показатели в диапазоне от -6143 до +6144; Имеет 34 цифры (т. е. 0,000000000000000000000000000000000-9.999999999999999999999999999999999).

Диапазон чисел от + -0,000000000000000000000000000000000x10−6143 до + -9,9999999999999999999999999999999999x10 + 6144

Мы можем обнаружить, что разница в диапазоне.

BigDecimal поддерживает специальный режим округления: UNLIMITED, но если мы используем UNLIMITED, Десятичный результат в бесконечном цикле вызовет исключение ArithmeticException.

Пример:

    public static void main(String[] args) {
    BigDecimal bd = new BigDecimal(1);
    BigDecimal bd2 = new BigDecimal(3);

    BigDecimal result = bd.divide(bd2, MathContext.DECIMAL32);
    System.out.println(result);
    result = bd.divide(bd2, MathContext.DECIMAL64);
    System.out.println(result);
    result = bd.divide(bd2, MathContext.DECIMAL128);
    System.out.println(result);
    result = bd.divide(bd2, MathContext.UNLIMITED);
    System.out.println(result);
}

Выход:

0.3333333
0.3333333333333333
0.3333333333333333333333333333333333
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

Итак, если вам нужен больший диапазон результатов, вы должны использовать decimal128 или UNLIMITED (но помните о десятичном цикле бесконечного цикла, он вызывает исключение ArithmeticException), в противном случае вам следует использовать decimal64 или decimal32, больший диапазон Beacuse означает худшую производительность.

...