C语言实现斐波那契数列第47项后输出负数的bug排查
问题根因:32位int类型整数溢出
你的斐波那契递推逻辑本身没有错误,输出异常是int类型的取值范围不足导致的。
目前绝大多数主流编译环境中,int为32位有符号整数,可表示的数值范围是-2147483648 ~ 2147483647(即-2^31到2^31-1)。你在代码中用int类型的s1、s2存储斐波那契计算结果:
- 按你设置的初始值:第1项为0、第2项为1,递推得到的第47项值为1836311903,这个值还在
int的取值范围内,所以输出正常。 - 第48项是第46项(1134903170)和第47项的和,计算结果为2971215073,已经超出32位有符号int的最大值2147483647,触发有符号整数溢出。C语言中有符号整数溢出属于未定义行为,最常见的表现是进位填充到符号位,数值直接变为负数,后续所有递推步骤的结果也会全部异常。
修复方法
把存储斐波那契数值的变量更换为取值范围更大的64位整数类型即可,主流环境下long long类型为64位有符号整数,取值范围覆盖-9223372036854775808 ~ 9223372036854775807,足够支持计算到第90项左右的斐波那契数不溢出。
如果需要计算序号更大的斐波那契数,需要额外实现大整数运算逻辑,用数组或字符串存储超大型数值。
修复后参考代码
#include <stdio.h> // Find Fibonacci Numbers ....... int main(){ long long s1, s2; int c, n; s1 = 0; s2 = 1; printf("Enter a number "); scanf("%d", &n); // 兼容n<2的输入场景 if (n >= 1) printf("1. %lld \n", s1); if (n >= 2) printf("2. %lld \n", s2); for(c = 3; c <= n; c++){ s2 = s1 + s2; printf("%d. %lld \n", c, s2); s1 = s2 - s1; } return 0; }
注意:更换为
long long类型后,printf输出对应数值的格式符要从%d改为%lld,否则会出现输出格式错误。
内容的提问来源于stack exchange,提问作者Nom
相关产品推荐
相关产品推荐

