将BigDecimal转换为double,提高性能

6

这是 BigDecimal.doubleValue() 的 Jdk7-b147 版本。

public double doubleValue(){
  if (scale == 0 && intCompact != INFLATED)
    return (double)intCompact;
  // Somewhat inefficient, but guaranteed to work.
  return Double.parseDouble(this.toString());
}

他们承认这种方法效率低下!有没有比使用这种方法更好/更快的方法?

1
准确性非常关键,将BigDecimal转换为double的逻辑非常复杂。(话虽如此,我有一个JDK补丁等待审核,可以将BigInteger.doubleValue()的速度提高两个数量级以上。) - Louis Wasserman
太棒了!你有补丁的链接吗? - durron597
2
https://bugs.openjdk.java.net/attachment.cgi?id=254&action=diff 是优化 BigInteger.{float,double}Value() 的补丁。Double.parseDouble 的逻辑与将 BigDecimal 转换为 double 几乎相同,可以在 sun.misc.FloatingDecimal 中看到它的混乱之处。 - Louis Wasserman
Louis,这正是我在寻找的东西。如果你将这些评论转化为答案,我会把它选为最佳答案。 - durron597
1个回答

11

BigDecimal转换为double没有更好的方法了。这是因为将foo * 10^bar高效地转换为baz * 2^quux,同时保持非常特定的舍入语义,算法非常麻烦和不愉快--有关详细信息,可参见sun.misc.FloatingDecimal,或阅读此文

另一方面,BigInteger.doubleValue()确实有很多优化机会,因为它只处理整数,而不需要处理小数分数。我有一个等待审核的JDK补丁,通过优化BigInteger.doubleValue(),可以提高它的效率超过两个数量级。

更新:这个修复已经添加到OpenJDK 8中,于2014年3月18日向公众发布。


@LouisWasserman 他们之前用来投票解决bug的功能取消了吗?我找到了这个链接(http://bugs.sun.com/view_bug.do?bug_id=7131192),但是我发现它自七月份以来就没有更新过了。你有更多关于他们何时会查看这个问题的信息吗? - durron597

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接