Scala中的精度错误迭代和范围

时间:2017-01-26 22:54:12

标签: scala collections precision

我试图建立一个有范围和步骤的双打集合。当我使用Array.iterate方法时,我会遇到奇怪的浮点错误:

scala> Array.iterate[Double](0.0, 10)(0.1+)
res0: Array[Double] = Array(0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999)

小步骤的小范围会导致这种不精确,这似乎很奇怪。我知道还有其他方法可以做到这一点(例如Array.iterate[Int](0, 10)(1+).map(i => i.toDouble / 10.0)),但我感到困惑的是内置的收集方法会表现得如此糟糕。这有什么原因,或者我是一个笨蛋,做错了吗?

2 个答案:

答案 0 :(得分:3)

这是浮点运算的一个基本限制的症状,与集合无关:

scala> 0.2 + 0.1
res0: Double = 0.30000000000000004

有很多帖子解释了为什么会发生这种情况:

答案 1 :(得分:1)

尝试使用BigDecimal:

scala> val r = BigDecimal(0) to BigDecimal(1) by BigDecimal(0.1)

scala> println(r)
NumericRange(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0)