我注意到这个构造函数有很大的痛苦(即使在Stack Overflow上也是如此)。人们使用它,即使文档明确指出:
此构造函数的结果可能有些不可预测 http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html#BigDecimal(double)
可能不推荐使用的现有规范:我们建议弃用BigDecimal(double)构造函数,该构造函数目前提供的结果与Double.toString()方法不同。
尽管如此,构造函数还没有被弃用。
我很想听到有关此事的任何意见。
答案 0 :(得分:20)
考虑到BigDecimal(double)
的行为是正确的,在我看来,我不太确定它真的会出现这样的问题。
我不完全同意BigDecimal(double)
构造函数中文档的措辞:
这个构造函数的结果可以是 有点不可预测。有人可能 假设在Java中编写
new BigDecimal(0.1)
创建了一个BigDecimal
完全等于0.1
(未缩放的1
值,缩放为1
),但实际上相等 至0.1000000000000000055511151231257827021181583404541015625
。
(强调补充。)
我认为措辞应该意外,而不是说不可预测的,即便如此,对于那些不了解代表性限制的人来说,这也是一种意想不到的行为带floating point values的十进制数字。
只要记住浮点值不能精确地表示所有十进制值,使用BigDecimal(0.1)
0.1000000000000000055511151231257827021181583404541015625
返回的值实际上是有意义的。
如果BigDecimal
构造函数实例化的BigDecimal(double)
对象是一致的,那么我认为结果是可预测的。
我猜测为什么BigDecimal(double)
构造函数没有被弃用是因为行为可以被认为是正确的,只要知道浮点表示如何工作,构造函数的行为就不会太令人惊讶。
答案 1 :(得分:2)
不推荐使用弃用。在特殊情况下,API的某些部分仅被标记为已弃用。
因此,在构建过程中运行FindBugs。 FindBugs有一个探测器PlugIn API,也是开源的(LGPL,IIRC)。
答案 2 :(得分:1)
与所有浮点运算一样,该特定构造函数是近似值。它并没有真正破碎,只是有缺点 只要做你的研究,小心处理它,你就不会有任何惊喜。在将十进制文字分配给双精度/浮点数时,你会遇到完全相同的事情。