为何n=100时该函数输出为0?整数溢出相关技术疑问
问题解释
首先明确函数的递归行为,结合静态变量r的特性分析:
函数递归逻辑拆解
函数中的static int r=0是静态存储变量,值会在函数调用间保留。我们梳理递归路径:
- 当
n>3时,r被赋值为当前n,返回f(n-2)*2,即所有大于3的n,函数值都是前一个间隔2的n的函数值乘以2。 - 当
n≤3时,返回f(n-1)+r,此时的r由上层n>3的调用赋值(比如计算f(4)时r=4,递归到f(2)时会沿用这个r值)。
实际计算前几个值可得规律:
f(4)=18,f(5)=32- 偶数
n=2k(k≥2):f(n)=18 * 2^((n/2)-2) - 奇数
n=2k+1(k≥2):f(n)=32 * 2^((n-5)/2)
int溢出与结果为0的原因
通常系统中int是32位有符号类型,范围为-2^31到2^31-1。C标准中整数溢出属于未定义行为,但多数编译器会按**补码循环(模2^32运算)**处理:数值超出范围后,取模2^32的结果作为最终值。
针对n在70-100范围的情况:
- 以n=70(偶数)为例:指数为
(70/2)-2=33,18*2^33=154618822656,这个数是2^32(4294967296)的整数倍,模运算后结果为0。 - 以n=71(奇数)为例:指数为
(71-5)/2=33,32*2^33=274877907968,同样是2^32的整数倍,模运算后结果为0。 - 对于n=100(偶数):指数为
(100/2)-2=48,18*2^48仍是2^32的整数倍,模运算后结果为0。
而n=50时,指数为(50/2)-2=23,18*2^23=150994944,该值小于2^31-1(2147483647),未发生溢出,因此是正整数。
内容的提问来源于stack exchange,提问作者Aniket Sinha Roy
相关产品推荐
相关产品推荐

