首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ArithmeticException在BigDecimal.divide期间抛出

ArithmeticException在BigDecimal.divide期间抛出
EN

Stack Overflow用户
提问于 2010-05-01 09:03:07
回答 8查看 33.1K关注 0票数 33

我认为java.math.BigDecimal应该是™对使用十进制数执行无限精度算术的需要的答案。

考虑以下片段:

代码语言:javascript
复制
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

代码语言:javascript
复制
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。否则,将返回除法的确切结果,与其他操作一样。

进一步浏览API,人们会发现,实际上存在着执行不精确划分的各种divide重载,即:

代码语言:javascript
复制
final BigDecimal third = one.divide(three, 33, RoundingMode.DOWN);
System.out.println(three.multiply(third));
// prints "0.999999999999999999999999999999999"

当然,现在最明显的问题是“有什么意义??”。我认为当我们需要精确的算术时,例如在财务计算时,BigDecimal是解决问题的方法。如果我们甚至不能准确地实现divide,那么这又能有多大的用处呢?它实际上是通用的吗,还是只在一个非常利基的应用程序中有用,而幸运的是,您根本不需要使用divide

如果这不是正确的答案,那么在财务计算中,我们能用什么来精确划分呢?(我的意思是,我没有金融专业,但他们仍然使用部门,对吧??)

EN

回答 8

Stack Overflow用户

发布于 2010-05-01 17:09:47

这个类是BigDecimal而不是BigFractional。从您的一些评论中,听起来您只是想抱怨没有在这个类中构建所有可能的数字处理算法。金融应用程序不需要无限的十进制精度;只是精确到所需的精确值(通常是0、2、4或5小数位)。

实际上,我已经处理过许多使用double的金融应用程序。我不喜欢它,但这就是它们的编写方式(也不是用Java编写的)。当存在汇率和单位换算时,就有可能出现四舍五入和瘀伤问题。BigDecimal消除了后者,但仍有前者用于除法。

票数 10
EN

Stack Overflow用户

发布于 2010-05-01 11:31:14

如果你想处理小数,而不是有理数,并且在最后的四舍五入(四舍五入)之前需要精确的算术(四舍五入),下面是一个小技巧。

你总是可以操纵你的公式,以便只有一个最后的除法。这样,你就不会在计算过程中失去精度,你就能得到正确的四舍五入的结果。例如

代码语言:javascript
复制
a/b + c

等于

代码语言:javascript
复制
(a + bc) / b.
票数 6
EN

Stack Overflow用户

发布于 2010-05-01 10:19:36

顺便说一句,我真的很感激从事金融软件工作的人的洞察力。我经常听到BigDecimal被提倡加倍

在财务报告中,我们使用标度=2和BigDecimal,因为报表中的所有打印值都必须导致可复制的结果。如果有人用一个简单的计算器来检查这个。

在瑞士,由于他们不再拥有1或2枚拉普硬币,所以他们的硬币的周转率为0.05。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2749375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档