如何避免Java / Kotlin / IntelliJ IDEA中的StackOverFlow错误?

我想做一个BigInteger的阶乘(在Kotlin中)。 有了尾递归,当我尝试做9000时,会出现StackOverFlow错误 。 有了一个非递归函数,我可以做到这一点…但我很好奇如何避免这种错误。

这是我的代码:

import java.math.BigInteger fun tail_recursion_factorial(n: BigInteger, factorialOfN: BigInteger = BigInteger.valueOf(2)): BigInteger { return when(n){ BigInteger.ONE -> BigInteger.ONE BigInteger.valueOf(2) -> factorialOfN else -> tail_recursion_factorial(n.minus(BigInteger.ONE), n.times(factorialOfN)) } } fun non_recursive_factorial(n: BigInteger): BigInteger{ var i: BigInteger = BigInteger.ONE var factorial: BigInteger = BigInteger.ONE while (i<=n){ factorial = factorial.times(i) i = i.plus(BigInteger.ONE) } return factorial } fun main(args: Array<String>){ print("n == ") var n = readLine()!! //recursive //println("$n! is ${tail_recursion_factorial(BigInteger(n))}") //non-recursive println("$n! is ${non_recursive_factorial(BigInteger(n))}") } 

这是一个必须在语言层面解决的问题,因为JVM不会优化尾递归。

幸运的是,Kotlin语言完全提供了tailrec修饰符,因此您可以简单地写tailrec fun而不是fun 。 编译器会将tailrec函数中的tail调用转换成循环,这应该消除你正在经历的堆栈溢出。