简体   繁体   中英

BigDecimal - MathContext.DECIMAL64 vs MathContext.DECIMAL128

I'm dealing with the divisions between monetary values. I'm currently using MathContext.DECIMAL128 as second parameter of BigDecimal.divide() . Should I use MathContext.DECIMAL128 or MathContext.DECIMAL64 ?

The difference between decimal32,decimal64,and decimal128 is (from https://bloomberg.github.io/comdb2/decimals.html ):

decimal32 supports exponents between -95 and +96; significand has 7 digits (ie 0.000000-9.999999).

The range of numbers representable by this format is +-0.000000x10−95 to +-9.999999x10+96

decimal64 supports exponents between -383 and +384; significand has 16 digits (ie 0.000000000000000-9.999999999999999). The range of numbers is +-0.000000000000000x10−383 to +-9.999999999999999x10+384

decimal128 supports exponents between -6143 and +6144; significand has 34 digits (ie 0.000000000000000000000000000000000-9.999999999999999999999999999999999).

The range of numbers is +-0.000000000000000000000000000000000x10−6143 to +-9.999999999999999999999999999999999x10+6144

We can find that the difference is range.

BigDecimal supports a special rounding mode:UNLIMITED,But if we use UNLIMITED, Infinite loop decimal result will throw a ArithmeticException.

Example:

    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);
}

Output:

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

So,if you want larger range of result,you should use decimal128 or UNLIMITED(but be aware of Infinite loop decimal,it will throw ArithmeticException),otherwise,you should use decimal64 or decimal32,Beacuse larger range means worse performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM