末尾再帰の例をいじっているときに、通常の再帰呼び出しと末尾再帰呼び出しの結果の間に小さな不一致があることに気づきました。
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
パラメーターはループの各反復で割り当てられ、小さな丸め誤差がそこに滑り込みます。