斐波那契数列C++计算中为何部分值为负、部分为正?
问题描述
我用C++写了一个计算斐波那契数列的程序,代码如下:
#include <iostream> using namespace std; int main() { int n, t1 = 0, t2 = 1, nextTerm = 0; cout << "Enter the number of terms: "; cin >> n; cout << endl; cout << "Fibonacci Series: "; for (int i = 1; i <= n; ++i) { // Prints the first two terms. if(i == 1) { cout << t1 << ", "; continue; } if(i == 2) { cout << t2 << ", "; continue; } nextTerm = t1 + t2; t1 = t2; t2 = nextTerm; cout << nextTerm << ", "; } cout << endl; return 0; }
当输入n=100时,生成的数列里出现了不少负值,我知道这是int类型的取值范围限制导致的,但疑惑为什么会出现部分值为负、部分值仍为正的情况?比如输出片段:-285007387, -945834654, -1230842041, 2118290601, 887448560, -1289228135, -401779575, -1691007710
完整输出如下:
Enter the number of terms: 100 Fibonacci Series: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, -1323752223, 512559680, -811192543, -298632863, -1109825406, -1408458269, 1776683621, 368225352, 2144908973, -1781832971, 363076002, -1418756969, -1055680967, 1820529360, 764848393, -1709589543, -944741150, 1640636603, 695895453, -1958435240, -1262539787, 1073992269, -188547518, 885444751, 696897233, 1582341984, -2015728079, -433386095, 1845853122, 1412467027, -1036647147, 375819880, -660827267, -285007387, -945834654, -1230842041, 2118290601, 887448560, -1289228135, -401779575, -1691007710, -2092787285, 511172301, -1581614984, -1070442683, 1642909629, 572466946, -2079590721, -1507123775, 708252800, -798870975, -90618175, -889489150, Process finished with exit code 0
解答
这是因为32位有符号整数的溢出会触发二进制补码的环绕行为,具体逻辑如下:
- 通常C++中的
int是32位有符号整数,取值范围是-2147483648到2147483647。当斐波那契数增长超过2147483647时,两个正数相加的结果会溢出,二进制最高位(符号位)被置为1,按补码规则解读就会变成负数。 - 后续的斐波那契数基于溢出后的负数继续计算:当两个负数相加的结果超出
-2147483648时,会再次溢出,符号位被置回0,解读为正数;或者一正一负相加的结果落在合法范围内时,也会得到正数或负数。 - 拿你给出的片段举例:
-1230842041和前一项-945834654相加,结果是-2176676695,这个数比32位int的最小值-2147483648还小,触发溢出。按补码规则,溢出结果会环绕成-2176676695 + 4294967296 = 2118290601,也就是你看到的正数。
简单来说,每次溢出都会让数值在正负区间里“绕圈”,所以会出现正负交替的情况。
内容的提问来源于stack exchange,提问作者Swapon Das
相关产品推荐
相关产品推荐

