BigDecimal - MathContext.DECIMAL64 与 MathContext.DECIMAL128
BigDecimal - MathContext.DECIMAL64 vs MathContext.DECIMAL128
我正在处理货币价值之间的分歧。我目前使用 MathContext.DECIMAL128
作为 BigDecimal.divide()
的第二个参数。我应该使用 MathContext.DECIMAL128
还是 MathContext.DECIMAL64
?
decimal32、decimal64、decimal128的区别是(来自https://bloomberg.github.io/comdb2/decimals.html):
decimal32 支持 -95 到 +96 之间的指数;有效数字有 7 位(即 0.000000-9.999999)。
此格式可表示的数字范围为+-0.000000x10−95 至+-9.999999x10+96
decimal64 支持 -383 到 +384 之间的指数; significand 有 16 位数字(即 0.000000000000000-9.999999999999999)。数字的范围是+-0.000000000000000x10−383 到+-9.999999999999999x10+384
decimal128支持-6143到+6144之间的指数; significand 有 34 位数字(即 0.000000000000000000000000000000000-9.999999999999999999999999999999999)。
数字的范围是+-0.000000000000000000000000000000000x10−6143到+-9.999999999999999999999999999999999x10+6144
我们可以发现区别在于范围。
BigDecimal支持特殊的舍入mode: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(但要注意无限循环 decimal,它会抛出 ArithmeticException),否则,你应该使用 decimal64 或 decimal32,因为更大的范围意味着更糟糕性能。
我正在处理货币价值之间的分歧。我目前使用 MathContext.DECIMAL128
作为 BigDecimal.divide()
的第二个参数。我应该使用 MathContext.DECIMAL128
还是 MathContext.DECIMAL64
?
decimal32、decimal64、decimal128的区别是(来自https://bloomberg.github.io/comdb2/decimals.html):
decimal32 支持 -95 到 +96 之间的指数;有效数字有 7 位(即 0.000000-9.999999)。
此格式可表示的数字范围为+-0.000000x10−95 至+-9.999999x10+96
decimal64 支持 -383 到 +384 之间的指数; significand 有 16 位数字(即 0.000000000000000-9.999999999999999)。数字的范围是+-0.000000000000000x10−383 到+-9.999999999999999x10+384
decimal128支持-6143到+6144之间的指数; significand 有 34 位数字(即 0.000000000000000000000000000000000-9.999999999999999999999999999999999)。
数字的范围是+-0.000000000000000000000000000000000x10−6143到+-9.999999999999999999999999999999999x10+6144
我们可以发现区别在于范围。
BigDecimal支持特殊的舍入mode: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(但要注意无限循环 decimal,它会抛出 ArithmeticException),否则,你应该使用 decimal64 或 decimal32,因为更大的范围意味着更糟糕性能。