在玩尾递归示例时,我注意到正常递归调用和尾递归调用的结果之间存在细微差异:
scala> def fact(n: Int): Double = if(n < 1) 1 else n * fact(n - 1)
fact: (n: Int)Double
scala> fact(30)
res31: Double = 2.6525285981219103E32
scala> @tailrec def fact(n: Int, acc: Double = 1): Double = if(n < 1) acc else fact(n - 1, n * acc)
fact: (n: Int, acc: Double)Double
scala> fact(30)
res32: Double = 2.652528598121911E32
只是出于好奇,有人可以向我解释为什么或在哪里进行舍入。我的猜测是,因为 Scala 编译器将尾递归版本转换为循环,所以acc
在循环的每次迭代中都会分配参数,并且小的舍入误差会滑入其中。