欧拉计划第二题 无穷?

5

我正在尝试解决欧拉计划 #2,但答案总是显示为“无限大”或“NaN”(不是一个数字)。我尝试将数字类型更改为int,但这没有解决问题,只给了我答案“-1833689714”。

public class Pro {
    static int g = 1;
    static int n, f = 0;
    public static void main(String args[]) {
        for (int i = 0; i <= 4000000; i++) {
            f = f + g;
            g = f - g;
            if (f % 2 == 0) {
                n += f;
            }
        }
        System.out.println("Answer: " + n);
    }
}

问题是:

斐波那契数列中的每个新项都是通过添加前两个项生成的。 从1和2开始,前10个项将是:

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

通过考虑斐波那契数列中值不超过四百万的项,找出偶数值项的总和。


你可能还想检查BigInteger类:http://docs.oracle.com/javase/6/docs/api/java/math/BigInteger.html - santiagozky
7个回答

8

您正在考虑斐波那契数列的前4,000,000个项,而不是前x个项,这些项不超过4,000,000。


谢谢,我还在清醒中 ;) 现在懂了。 - Spencer H

3
您的问题是整数溢出:在Java中,int变量被限制为Integer.MAX_VALUE(2147483647)。如果您在计算中超过此值,则会溢出到Integer.MIN_VALUE,即最小的负值。请参见:
public class IntegerOverflow {
    public static void main(String[] args) {
        int i = Integer.MAX_VALUE;
        System.out.println("i = Integer.MAX_VALUE: " + i);
        System.out.println("i + 1: " + (i + 1));
        System.out.println("i + 2: " + (i + 2));
    }
}

为了避免溢出问题,使用由java.math.BigInteger类提供的任意精度整数进行计算:
import java.math.BigInteger;

public class BigIntegerExample {
    public static void main(String[] args) {
        BigInteger b = BigInteger.valueOf(Long.MAX_VALUE);
        System.out.println("b = Long.MAX_VALUE: " + b);
        System.out.println("b**2: " + b.multiply(b));
        System.out.println("b**3: " + b.pow(3));
        System.out.println("b**10: " + b.pow(10));
    }
}

注意:由于您并没有请求有关问题本身的帮助,因此我只是回答了这个问题。希望这可以帮到您。


1
这个问题只需要一个 int - Jeffrey
你说得没错,但在这个问题中使用BigInteger的性能损失微不足道,并且使用BigInteger您不必担心溢出问题。 - Danilo Piazzalunga
+1 鼓励回答问题并在 PE 帮助的精神内保持。 - Austin Salonen

2
您可能遇到了溢出问题。 fibo(4000000) 远远超过了MAX_INT
请注意:您不是要找到前400万个数字中的偶数之和,而是要找到其值不超过4,000,000的偶数元素的总和。
您应该检查f<4000000,如果不是,则停止计算,而不是等待i达到4,000,000。

1
你正在检查前400万个斐波那契数列,只需要检查到一个斐波那契数大于400万就停止。你得到负数的原因是最终得到的斐波那契数超过了Integer.MAX_INT,此时会发生溢出并开始得到负数,而你将其加入了总和中。如果你不确定最终答案是否会超过Integer.MAX_INT,应该使用long作为累加器,而不是int。

0

在C语言中使用GMP处理大数。 在开始之前多思考一下也不会有坏处(例如奇数和偶数的出现频率,斐波那契数列的前n个元素的总和是多少)...


1
这不是 C,Java 有其本地的 BigInteger 类。此外,对于这个问题来说,long 已经足够了。 - amit
使用 long 可能已经足够了,但是在高精度计算中,推荐使用 BigInteger:http://docs.oracle.com/javase/tutorial/java/data/numberclasses.html - Danilo Piazzalunga
@DaniloPiazzalunga 但是对于这个问题,您不需要进行高精度计算。一切都可以在int范围内轻松完成。 - Daniel Fischer

0
你可以使用long代替int
每3个表达式中有一个是偶数,所以只需要计算每个第三个值。这样稍微快一些,因为循环次数更少,而且不需要测试奇偶性。
你只需要n,而不是小于400万的i

0
这是我得到答案的方法:
def fib():
        x,y = 0,1
        while True:
            yield x
            x,y = y, x+y

def even(seq):
    for number in seq:
        if not number % 2:
            yield number

def under_a_million(seq):
    for number in seq:
        if number > 4000000:
            break
        yield number   

print sum(even(under_a_million(fib())))

-M1K3


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接