【问题标题】:Why is the Bigdecimal(double d) construction still around?为什么 Bigdecimal(double d) 结构仍然存在?
【发布时间】:2010-11-06 14:28:10
【问题描述】:

我注意到这个构造函数非常痛苦(即使在 Stack Overflow 上也是如此)。即使文档明确指出,人们也会使用它:

这个构造函数的结果可能有些不可预测 http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html#BigDecimal(double)

我什至看到JSR-13APPROVED 并附有推荐说明:

可能被弃用的现有规范:我们建议弃用 BigDecimal(double) 构造函数,它目前给出的结果与 Double.toString() 方法不同。

尽管如此,构造函数尚未被弃用。

我很想听听对此的任何看法。

【问题讨论】:

    标签: java api bigdecimal


    【解决方案1】:

    考虑到BigDecimal(double) 的行为是正确的,在我看来,我不太确定它是否真的会是这样的问题。

    我不完全同意 BigDecimal(double) 构造函数中文档的措辞:

    这个构造函数的结果可以是 有点不可预测。一个可能 假设用 Java 编写 new BigDecimal(0.1) 会创建一个 BigDecimal 正好等于 0.1(未缩放的值1,缩放为1),但实际上是相等的 到 0.1000000000000000055511151231257827021181583404541015625.

    (已添加重点。)

    与其说unpredictable,我认为措辞应该unexpected,即便如此,这对于那些不知道representation的局限性的人来说也是意想不到的行为floating point values 的十进制数。

    只要记住浮点值不能精确地表示所有十进制值,使用BigDecimal(0.1)返回的值是0.1000000000000000055511151231257827021181583404541015625实际上是有意义的。

    如果BigDecimal(double) 构造函数实例化的BigDecimal 对象是一致的,那么我认为结果是可预测的。

    我猜测为什么BigDecimal(double) 构造函数没有被弃用是因为它的行为可以被认为是正确的,只要知道浮点表示是如何工作的,构造函数的行为就不会太令人惊讶了。

    【讨论】:

    • 伟大的论点! ">只要知道浮点表示是如何工作的" ...猜测这句话消除了大约 95% 的编程世界(可能更多)。防止那些 95% 的程序员造成数百万美元的会计错误可能是促使 JSR-13 提出该建议的原因:)
    • 根据推理(不仅)必须尽快删除双精度和浮点数
    • 重要的是计算机科学家要记住并不是所有的浮点值都可以表示,但我不认为这意味着这个构造函数是好的。虽然某些浮点值不能用双精度表示,但 IMO 应该没有理由在使用双精度构造函数时会错误地表示那些浮点值。事实上,更糟糕的是这个类中的其他文档暗示了构造函数的弱点docs.oracle.com/javase/7/docs/api/java/math/…
    【解决方案2】:

    弃用已弃用。部分 API 仅在特殊情况下被标记为弃用。

    因此,在构建过程中运行 FindBugs。 FindBugs 有一个检测器插件 API,也是开源的(LGPL、IIRC)。

    【讨论】:

    【解决方案3】:

    与所有浮点运算一样,该特定构造函数是一个近似值。它不是真的坏,它只是有缺点。
    只要做你的研究,小心处理它,你不会得到任何惊喜。将十进制文字分配给双精度/浮点数时,您会遇到完全相同的事情。

    【讨论】:

    • 好点,对于毫无戒心的开发人员来说,它就像一个地雷。从长远来看,地雷从来没有为任何人服务过……这就是我猜 JSR 的原因……
    猜你喜欢
    • 2017-02-17
    • 2013-06-17
    • 2011-08-03
    • 1970-01-01
    • 2021-02-01
    • 2011-02-26
    • 2014-10-09
    • 1970-01-01
    • 2015-09-30
    相关资源
    最近更新 更多