我试图在Scala(和/或Java)中以大于 double 的固定精度进行计算。我将BigDecimals与Scala的默认MathContext配合使用,其精度为34。即使所有输入都具有此精度,我发现经过几次计算,结果的精度开始爆炸。

这是我认为可以说明问题的示例计算:

import math.BigDecimal

val z40 = BigDecimal(0).setScale(40) // 0E-40
z40.scale                            // 40
z40.precision                        // 1
(1 + z40*z40).precision              // 81

结果为81,其精度比z40高。就我而言,我从未使用过setScale,但是在计算中会出现具有非常大比例的零。

这不是我想要的行为。我希望(1 + z40*z40)的精度为34-在其中执行计算的MathContext的精度(因为z40*z40与1相比很小,可以忽略不计)。我如何获得这种算术?

更新:此行为是由于Scala 2.9。*和2.10。*之间存在change in the handling of MathContexts而引起的。 (感谢Paul Phillips指出了提交。)另请参见this discussion

最佳答案

似乎很奇怪。我尝试了您的代码,并按预期获得了结果:

$ scala
Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_10).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import math.BigDecimal
import math.BigDecimal

scala> val z40 = BigDecimal(0).setScale(40)
z40: scala.math.BigDecimal = 0E-40

scala> z40.scale
res0: Int = 40

scala> z40.precision
res1: Int = 1

scala> (1 + z40*z40).precision
res2: Int = 34

scala> _

如您所见,(1+z40*z40).precision是您期望的34

10-05 23:03