甚至斐波那契的总和

时间:2015-05-14 04:04:10

标签: java

当我将4000000放入方法的参数大小,即fib(4000000)时,我不确定为什么我的代码会产生错误的负值?

问题是:

  

Fibonacci序列中的每个新术语都是通过添加前两个术语生成的。从1和2开始,前10个术语将是:

     

1,2,3,5,8,13,21,34,55,89,......

     

通过考虑Fibonacci序列中的值不超过四百万的项,找到偶数项的总和。

我的第一个代码:

public void fib(int k) {

    int result = 0;
    int[] array = new int[k];
    array[0] = 1;
    array[1] = 2;

    for (int i = 2; i < k; i++) {
        array[i] = array[i - 2] + array[i - 1];       
    }

    for (int even: array) {

        if (even % 2 == 0) {
            result += even;
        }
    }        
    System.out.println(result);
}

哪个没有用,所以我认为这是因为数组大小太大(四百万很多)所以我试着写一个不同的代码:

public void fib(int k) {

    int sum = 0;
    int term1 = 1;
    int term2 = 2;
    int term3 = 0;
    int i = 2;

    while (i < k) {

        term3 = term1 + term2;

        term1 = term2;
        term2 = term3;
        i++;

        if (term2 % 2 == 0) {
            sum += term2;
        }
    }   

    System.out.println(sum + 2);

}

哪个也没有用。

我的代码出了什么问题?对于少数size它可以工作,但是对于它来说它不起作用。

在我搜索了我发现的问题的答案之后:

    int term1 = 1;
    int term2 = 2;
    int i = 0;
    int result = 0;

    while (term1 < 4000000) {
        i = term1;
        term1 = term2;
        term2 = term2 + i;

        if (term2 % 2 == 0) {
            result += term2;
        }
    }
    System.out.println(result);

有效。

2 个答案:

答案 0 :(得分:4)

我认为你不会遇到溢出问题。我认为你的问题有点不正确。它说你应该查看所有斐波那契数字,其中数字的值<= 4百万。相反,你正在查看前400万斐波那契数字。这是它之间的区别:

  

1,2,3,5,8(所有纤维数小于10)

和此:

  

1,2,3,5,8,13,21,34,55,89(前10个纤维数)

我认为它需要前者,但你正在做后者。

而不是:

while (i < k) {

如果你这样做怎么办?

while (term1 < k) {

答案 1 :(得分:3)

根据doc

  

默认情况下,int数据类型是32位带符号的二进制补码   整数,最小值为-2 ^ 31,最大值为   2 ^ 31-1。

您将总和存储在result中,这是一个int,它将溢出。如下所示,重新获得它,它将起作用:

public static void fib(int size) {

        long result = 0;
        int[] array = new int[size];
        array[0] = 1;
        array[1] = 2;

        for (int i = 2; i < size; i++) {
            array[i] = array[i - 2] + array[i - 1];
        }

        for (int even: array) {
            if (even % 2 == 0) {
                result += even;
            }
        }
        System.out.println(result);
    }

fib(4000000)的值现在为2111290219918。签名的long的最小值为-2^63,最大值为2^63-1