Scala 2.10在BigDecimal中似乎失去了精度

时间:2019-03-27 21:36:49

标签: java scala 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)

请参见下面的调试器输出,断点位于测试断言上

Debugger Screenshot

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

1 个答案:

答案 0 :(得分:2)

这是由于使用默认的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)
  }

}