Während mit einem Endrekursion Beispiel liebäugelt bemerkte ich eine kleine Diskrepanz zwischen den Ergebnissen eines normalen rekursive Aufruf und einem Schwanz rekursive Aufruf:Warum gibt es einen Rundungsunterschied zwischen meinem Beispiel für normale Rekursion und Tail-Rekursion?
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
Nur aus Neugier, kann mir bitte jemand erklären, warum oder wo die das Runden geschieht. Meine Vermutung ist, dass, weil der Scala-Compiler die rekursive Tail-Version in eine Schleife übersetzt, der Parameter acc
bei jeder Iteration der Schleife zugewiesen wird, und dass der kleine Rundungsfehler dort hineinrutscht.
In einer geeigneten Programmiersprache, wie Scala wird, wird ein Rundungsfehler nicht ein 'Double' Ergebnis zu einer' Double' Variablen zugewiesen einzuführen. –