私は、通常の再帰呼び出しの結果と末尾再帰呼び出しの間に小さな食い違いに気づい末尾再帰の例をいじる中:通常の再帰の例と末尾の再帰の例の間に丸めの違いがあるのはなぜですか?
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
パラメータが割り当てられ、小さな丸め誤差がそこに入ることになります。
Scalaのような適切なプログラミング言語では、「Double」変数に「Double」結果を代入しても丸め誤差が発生しません。 –