Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用递归斐波那契函数时发生堆栈溢出错误_Java_Stack Overflow - Fatal编程技术网

Java 使用递归斐波那契函数时发生堆栈溢出错误

Java 使用递归斐波那契函数时发生堆栈溢出错误,java,stack-overflow,Java,Stack Overflow,这是我的代码,它在400到4000的值下运行良好,但一旦达到4mil左右,就会出现堆栈溢出错误 提前谢谢 public class Fib { static int c=1,b=2; static long sum1=0,sum2=0; static long fib(long a){ if(a==1){ return 1; } if(a==2){ return 2; } else{ return fib(a-1)+fib(a-2); } } pu

这是我的代码,它在400到4000的值下运行良好,但一旦达到4mil左右,就会出现堆栈溢出错误

提前谢谢

public class Fib {
static int c=1,b=2;
static long sum1=0,sum2=0;

static long fib(long a){
if(a==1){
    return 1;
}
if(a==2){
    return 2;
}
else{
    return fib(a-1)+fib(a-2);
}

    }


    public static void main(String[] args){
sum2= fib(4000000);
    System.out.println("Sum %f" +sum2);
}
    }

是-堆栈空间不足。它远不是无限的,每次递归调用都会用到它。你试图得到一个有400万个堆栈帧的堆栈,这是行不通的


我建议你考虑一个迭代方法。即使有无限多的堆栈,这些代码也可能在宇宙热死之前无法完成。(想想这段代码的复杂性…

您可以增加Java程序的堆栈大小。例如:

java -Xss4m YourProgram


尽管如此,我还是推荐一种迭代方法。

正如Jon Skeet所提到的,您的代码需要大量的时间来运行—2到400万次,这在任何方面都是不实际的。坦率地说,我很惊讶堆栈会干涸,我认为代码会运行很长时间

您应该使用迭代方法。下面是斐波那契序列的一个更好的实现:

static long fib(long i){
    if ( i == 0 || i == 1 ) return 1;
    long a = 1; //This is the 0th element 
    long b = 1; //This is the 1st element
    while( i-- > 1 ){ //Each iteration, sets a and b to the next element in the fibonacci sequence
        long temp = b;
        a += b;
        b = a;
        a = temp;
    }
    return b;
}

问题是什么?你知道你的机器有有限的资源,对吧?递归函数在堆栈上运行,堆栈并不是无止境的。你得到堆栈溢出错误是因为你的堆栈溢出了…因为计算4.000和4.000.000时所需的资源差异很小。400万是完全不合理的输入;Fib的生长是爆炸性的。仅第四百万项就有将近一百万位。整数从-2147483648到2147483647,因此您可以使用
int
而不是
float
@PRamesh:这里不需要对参数使用
long
,因为400万在int的范围内。但是,fib(4000000)的结果当然不能适应很长时间。你会得到一个结果,但它会绕了很多圈,因为加上两个大数字会得到一个负数……除非你得到算术溢出错误,否则
long
没有错。虽然您不需要在类中声明它。@SideshowBob:将长字符相加不会导致算术溢出错误。。。它会溢出,但不会出错。这是假设每个堆栈帧有一个字节。我怀疑那不会起作用。。。