我正在使用BigDecimal,我知道如果我除法,必须使用MathContext并按照文档中的说明告诉ScaleRoundingMode避免ArithmeticException


  在除法的情况下,精确商可以具有无限大
  长十进制扩展;例如1除以3。
  具有无终止的十进制扩展,并且已指定操作
  要返回精确结果,将引发ArithmeticException。


在我正在使用的方法中,我必须将来自我们数据库的金额(四舍五入为两位小数)与来自外部服务的金额相加,并且我不知道这些金额的确切比例(可能为3位小数) 。

我的问题是,我可以信任BigDecimal的add方法并在不进行四舍五入和缩放的情况下使用它吗?还是始终指定所需缩放比例的好习惯?

在某些特殊情况下,加减法会引起ArithmeticException吗?

最佳答案

如果结果的小数位数不适合BigDecimal.add(),则ArithmeticException将抛出int

一个简单的示例是将两个数字分别以最大和最小比例相加:

BigDecimal a = new BigDecimal(BigInteger.ONE, Integer.MIN_VALUE);
BigDecimal b = new BigDecimal(BigInteger.ONE, Integer.MAX_VALUE);
a.add(b);


如果您的应用程序需要以这种规模运行,那么与担心算术异常相比,您可能会遇到更大的问题。

在不使用MathContext的情况下添加数字将保持适当的比例并为您提供精确的结果。根据实际值,此方法可以使用任意数量的内存来表示越来越长的数字,而更长的数字需要花费更多的时间来添加。

在不使用MathContext的情况下添加数字并在求和后进行一次路由将使您精确的结果四舍五入到所请求的MathContext。内存和计算成本与第一种情况相同。

对每个加法使用MathContext会产生与预大小结果相差任意值的结果,但是内存和速度会更容易受到影响。

选择使用哪种方法真正取决于任务的性质,因此您需要评估和选择适合每种情况的正确方法。

07-24 09:15