Java斐波那契序列代码出现负数,请问问题出在哪里?
为什么我的Java斐波那契代码输出负数?
嘿,这个问题其实是整数溢出导致的,这是Java里处理整数时很容易踩的坑!
咱们先来理清楚原因:Java里的int类型是有符号的32位整数,它的取值范围是 -2147483648 到 2147483647。当你生成的斐波那契数超过这个范围的最大值时,就会发生溢出——因为有符号整数溢出后会按照补码规则循环,结果就变成负数了。
看你的代码,循环要生成4000个斐波那契数,但其实第46个斐波那契数就已经超过int的最大值了(第46个是1836311903,第47个就是2971215073,远超2147483647),所以从第47个数开始,就会溢出变成负数,后面的数自然也都是异常的。
解决办法
这里有两种常用的修复方案:
1. 改用long类型
long是64位有符号整数,范围能到 -9223372036854775808 到 9223372036854775807,能容纳大概前90个斐波那契数,足够覆盖你现在4000次循环里前90个的需求(再往后还是会溢出,但比int能撑很久)。修改后的代码大概是这样:
import java.util.ArrayList; import java.util.List; public class Fibonacci { private List<Long> fibonacci; // 把类型改成Long public void fillFibonacci() { fibonacci = new ArrayList<>(); long n1 = 1, n2 = 1, n3; // 变量类型改成long fibonacci.add(n1); fibonacci.add(n2); for (int i = 2; i < 4000; i++) { n3 = n1 + n2; fibonacci.add(n3); n1 = n2; n2 = n3; } } public void printFibonacci() { for (int i = 0; i < fibonacci.size(); i++) { System.out.print(fibonacci.get(i) + " "); System.out.println(i); } } }
2. 使用BigInteger(无溢出风险)
如果真的需要生成4000个斐波那契数,那long也会溢出,这时候就得用java.math.BigInteger——它支持任意精度的整数,完全不会有溢出问题。修改后的代码示例:
import java.math.BigInteger; import java.util.ArrayList; import java.util.List; public class Fibonacci { private List<BigInteger> fibonacci; public void fillFibonacci() { fibonacci = new ArrayList<>(); BigInteger n1 = BigInteger.ONE; BigInteger n2 = BigInteger.ONE; fibonacci.add(n1); fibonacci.add(n2); for (int i = 2; i < 4000; i++) { BigInteger n3 = n1.add(n2); // 用add方法代替+ fibonacci.add(n3); n1 = n2; n2 = n3; } } public void printFibonacci() { for (int i = 0; i < fibonacci.size(); i++) { System.out.print(fibonacci.get(i) + " "); System.out.println(i); } } }
这样修改后,你就能得到正确的斐波那契序列,不会再出现负数啦!
内容的提问来源于stack exchange,提问作者Laila Mattar
相关产品推荐
相关产品推荐

