Scala 2.10 似乎失去了 BigDecimal 的精度

Scala 2.10 seems to lose precision in BigDecimal

以下测试在 Scala 2.11 和 2.12 中通过,但在 2.10 中失败

class JsonToXmlParserTest extends Suite with Matchers with AssertionsForJUnit {
  @Test
  def testBigDecimalPrecision(): Unit = {
    val decimalString = "12345678901234567890.12345678901234567890"
    val bigDecimal = BigDecimal(decimalString)
    val javaBigDecimal = new java.math.BigDecimal(decimalString)

    javaBigDecimal.compareTo(bigDecimal.bigDecimal) should be(0)
  }

}
org.scalatest.exceptions.TestFailedException: -1 was not equal to 0
    at org.scalatest.MatchersHelper$.indicateFailure(MatchersHelper.scala:346)
    at org.scalatest.Matchers$ShouldMethodHelper$.shouldMatcher(Matchers.scala:6668)
    at org.scalatest.Matchers$AnyShouldWrapper.should(Matchers.scala:6704)

查看下面的调试器输出,断点在测试断言上

BigDecimal精度是 Scala 2.10 中的已知问题吗?

这是由于使用了默认的MathContext造成的。 Scala 2.10 使用的 MathContext 精度为 34 个字符,Scala 2.11 似乎使用的精度为 40 个字符。为了解决这个问题,我可以指定 MathContext 使用无限精度,这样更改测试如下,所有 scala 版本都通过

class JsonToXmlParserTest extends Suite with Matchers with AssertionsForJUnit {
  @Test
  def testBigDecimalPrecision(): Unit = {
    val decimalString = "12345678901234567890.12345678901234567890"
    val bigDecimal = BigDecimal(decimalString, MathContext.UNLIMITED)
    val javaBigDecimal = new java.math.BigDecimal(decimalString, MathContext.UNLIMITED)

    javaBigDecimal.compareTo(bigDecimal.bigDecimal) should be(0)
  }

}