我认为java.math.BigDecimal
应该是使用十进制数执行无限精度算术的 The Answer™。
考虑以下代码段:
import java.math.BigDecimal;
//...
final BigDecimal one = BigDecimal.ONE;
final BigDecimal three = BigDecimal.valueOf(3);
final BigDecimal third = one.divide(three);
assert third.multiply(three).equals(one); // this should pass, right?
我希望assert
通过,但实际上执行甚至没有到达那里:one.divide(three)
导致ArithmeticException
被抛出!
Exception in thread "main" java.lang.ArithmeticException:
Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide
事实证明,这种行为已明确记录在API中:
在 的情况下
divide
,精确商可以有无限长的小数展开;例如,1 除以 3。如果商具有非终止的十进制扩展并且指定操作返回精确结果,ArithmeticException
则抛出 an。否则,将返回除法的确切结果,就像其他操作一样。
进一步浏览 API,发现实际上有各种重载divide
执行不精确的除法,即:
final BigDecimal third = one.divide(three, 33, RoundingMode.DOWN);
System.out.println(three.multiply(third));
// prints "0.999999999999999999999999999999999"
当然,现在明显的问题是“有什么意义???”。我认为BigDecimal
这是我们需要精确算术时的解决方案,例如财务计算。如果我们甚至不能divide
完全准确,那么这有多大用处?它实际上是用于通用目的,还是仅在您完全不需要的非常利基的应用程序中有用divide
?
如果这不是正确答案,我们可以使用什么来进行财务计算中的精确划分?(我的意思是,我没有金融专业,但他们仍然使用除法,对吗???)。