Scala double列表上的foldLeft返回奇怪的值

Scala double列表上的foldLeft返回奇怪的值,scala,floating-point,Scala,Floating Point,在尝试使用foldLeft对不同实例中包含的双精度列表求和时,我遇到了一个奇怪的问题。经调查,似乎即使在处理简单替身列表时,问题仍然存在: val listOfDoubles = List(4.0, 100.0, 1.0, 0.6, 8.58, 80.0, 22.33, 179.99, 8.3, 59.0, 0.6) listOfDoubles.foldLeft(0.0) ((elem, res) => res + elem) // gives 464.40000000000003 ins

在尝试使用
foldLeft
对不同实例中包含的双精度列表求和时,我遇到了一个奇怪的问题。经调查,似乎即使在处理简单替身列表时,问题仍然存在:

val listOfDoubles = List(4.0, 100.0, 1.0, 0.6, 8.58, 80.0, 22.33, 179.99, 8.3, 59.0, 0.6)
listOfDoubles.foldLeft(0.0) ((elem, res) => res + elem) // gives 464.40000000000003 instead of 464.40
我做错了什么

注意:
foldLeft
这里是必要的,因为我试图实现的是
case类SomeClass(value:Double)
的不同实例中包含的一个Double的总和,当然,除非有其他方法可以实现这一点

我做错了什么

在需要这种精度时使用双精度。这不是foldLeft的问题。您正遭受浮点舍入错误。问题是一些数字需要非常长(或无限)的二进制表示,这意味着它们需要以二进制形式截断。当转换回十进制时,二进制舍入误差就会显现出来

请改用
BigDecimal
,因为它的设计可以实现任意精度

scala> val list: List[BigDecimal] = List(4.0, 100.0, 1.0, 0.6, 8.58, 80.0, 22.33, 179.99, 8.3, 59.0, 0.6)
list: List[BigDecimal] = List(4.0, 100.0, 1.0, 0.6, 8.58, 80.0, 22.33, 179.99, 8.3, 59.0, 0.6)

scala> list.foldLeft(BigDecimal(0.0))(_ + _)
res3: scala.math.BigDecimal = 464.40
或者简单地说:

scala> list.sum
res4: BigDecimal = 464.40
我做错了什么

在需要这种精度时使用双精度。这不是foldLeft的问题。您正遭受浮点舍入错误。问题是一些数字需要非常长(或无限)的二进制表示,这意味着它们需要以二进制形式截断。当转换回十进制时,二进制舍入误差就会显现出来

请改用
BigDecimal
,因为它的设计可以实现任意精度

scala> val list: List[BigDecimal] = List(4.0, 100.0, 1.0, 0.6, 8.58, 80.0, 22.33, 179.99, 8.3, 59.0, 0.6)
list: List[BigDecimal] = List(4.0, 100.0, 1.0, 0.6, 8.58, 80.0, 22.33, 179.99, 8.3, 59.0, 0.6)

scala> list.foldLeft(BigDecimal(0.0))(_ + _)
res3: scala.math.BigDecimal = 464.40
或者简单地说:

scala> list.sum
res4: BigDecimal = 464.40
对根本原因有很好的解释(Scala中有几个例子)对根本原因有很好的解释(Scala中有几个例子)