首页 > 试题广场 >

下面的程序中, int32

[单选题]
下面的程序中, int32-t 表示一个有符号的 32 位整数,程序的入口是 main 函数,问最终 res 的结果是多少?
#include <stdint.h>
#include <stdio.h>
int32_t f(int32_t a, int32_t b) {
	while (a + b > 0) {
		a = a + 1;
		b = b - 1;
	}
	return a + b;
}
int32_t main() {
	int32_t res = f(1, 0);
	return 0;
}



  • –(2^31+2^30+…+2^2+2^1+2^0)
  • 0
  • -1
  • 程序会死循环
这题是不是有问题???
感觉答案是1:
将题目中的int32改为char分析:
f(1,0):
        a=2  b=-1
        a=3  b=-2
        ......
        a=127 b=-126
        a=128 b=-127  溢出-->a=-128 b=-127     char范围:-128~127      
 return a+b:-128-127实际上是1(char范围)   


发表于 2017-01-17 10:35:50 回复(12)
@ 羽落长安  的解析不错,以char为例
f(1,0):
        a=2  b=-1
        a=3  b=-2
        ......
        a=127 b=-126
        a=128 b=-127  溢出-->a=-128 b=-127     char范围:-128~127       
 return a+b:-128-127实际上是1(char范围),继续循环

而原例为int_32t,临界情况 a+b:      -2^32+(-2^32+1)=1,也继续循环。

因此死循环。
发表于 2017-02-18 13:27:13 回复(5)
发表于 2017-08-16 00:51:44 回复(1)
依据计算机存储数的都是2进制,根据不同类型来解释这个数的本质。这个题可以这样分析:
a+b=0000.....0001+0000....0000
a+1=0000.....0010
b-1= 1111......1111
所以
a+b= 0000.....0001
此时不要考虑什么溢出了,要知道在加法器里面只是根据补码来对应位相加。
所以a+b的2进制表示永远为0000001,所以一直是死循环。具体可以参考《微机原理》
发表于 2018-05-13 22:04:54 回复(0)

char+char的结果会自动转化成int,所以(char)-128+(char)-127 = (int)-255。此时停止循环
但是int32+int32结果仍为int32,所以不会停止循环
发表于 2017-07-09 09:22:46 回复(0)
1)知识点: 一个数据类型的最大值和最小值是一个循环,也就是说在最大值的基础上再扩大数值或者在最小值的基础上再缩小数值,会跳到相反的最值上面。
2) 本题:
   a = 2  b = -1
 ①  a = 2^32 -  1;  b = - 2^32 + 2 
   而 32位数的范围是 -2^32 到  2^32 - 1

   ②则 继续变化
   a = 2^32 ----> 变成了 -2^32
   b = - 2^32 + 1
  a + b = -2^32 + (-2^32 + 1) = (-2^32  - 1)+ (-2^32 + 2)  =( 2^32 - 1)  + (-2^32 + 2)  = 1  > 0

  ③  a = -2^32 + 1
    b = -2^32 
  a + b = (-2^32 + 1) + (-2^32) = 1 > 0

④ a = -2^32 + 2
 b = -2^32 - 1 ----->变成了 2^32 - 1
a + b = (-2^32 + 2) + (2^32 - 1) = 1 > 0

.... a继续变大,b继续变小
   a = 2^32 -  1;  b = - 2^32 + 2 
即由变成了 ①中的情况,由此便出现了 无限循环的情况

编辑于 2022-01-08 16:44:15 回复(0)
该题重点在于while中的表达式a+b的类型。如果将int32_t该为char来分析,当a=127,b=-126时,a+b==1,while继续,a=a-1,b=b-1得a==-128,b==-127,此时a+b表达式以int存储结果,故跳出循环。而由于返回值类型为char,则a+b保留低8位,故返回值为1。而当以int32_t分析,a=-2^31,b=1-2^31时,两者相加的结果以int32_t保存,得1,故循环继续。此后,a+b的值总是为1,且a,b的值又会回到1,0。如此循环,从而导致死循环。
发表于 2017-08-24 16:24:37 回复(2)
感觉这题目不严谨,在某些编译器下
如果int超过了INT_MAX报错,但是在某些编译器下又不会(貌似leetcode还是牛客的C++编译器,有符号整型溢出就报错)。
在编译器不报错的情况下
那么a达到INT_MAX之后,b的值尾  -(INT_MAX-1)
此时a+1,则符号位为1,其余位为0,此时a为
1000 0000 0000 ...
按照规定此时a为INT_MIN
而b此时为 -INT_MAX
此时
INT_MIN+ -INT_MAX  此时又溢出了,但是溢出不报错
以8位距离
INT_MIN 1000 0000
-INT_MAX 1111 1111 源码
                  1000 0001补码
1000 0000
1000 0001

0000 0001
得到1,所以程序此时还在循环
如果a再加1
a = -INT_MAX
b = INT_MIN
结果还是1
再往下
a = -(INT_MAX-1)
b = INT_MAX
a 1111 1110 源
   1000 0010
b 01111 1111
    0000  0000 
0000 0001
还是1

所以死循环了

下面说用char类型得到结果是1的原因是
char是无符号类型,取值范围是0~255.
想一下哪个ASCII码对应的是负值?
编辑于 2020-04-04 00:56:40 回复(0)
答案 :程序会死循环。注意a和b分别到达边界值,然后溢出的情况
1. 一直加,a先达到int的边界,正数最大值
    a=1 ,b=0 ,  
    a+1 一直加到a = 2^32-1 ,  a达到了int正数最大值 ; 
    这时b = -2^32-2

2. 然后a溢出
     a+1,溢出,a+1 = -2^32 , int的负数最大值 ; 
     这时b-1=-2^32-1

3. 然后 b达到int边界,负数最大值
    a+1 = -2^32+1
    b-1 = -2^32  ,int负数最大值,

4. 然后 b 溢出
    a+1 = -2^32+2
    这时b-1,溢出,b-1 = 2^32-1,为int整数最大值,
   
4.目前     a =-2^32+2  ;  b= 2^32-1
   继续会发生 a一直加到0,b会减到 1
   进入循环

注:char是有符号位8bit整数,虽然ASCII码没有负数对应的字符,但是还是可以打印出来(int形式的)。这道题可以拿char类型去分析。实际上,你拿两个bit都能分析,虽然没有实际意义。

关于溢出计算,首先整数的原码和补码是一样的,计算机中以补码存储,计算也以补码进行。
int整数最大值为2^32 -1 ,即0111 1111 ,整数的原码和补码是一样的。
int负数最大值是 -2^32 ,它没有原码和反码,只有补码,1000 0000 。
那  0111 1111 + 000 0001 = 1000 0000 ,按位从右往左加,计算机存储的是1000 0000 ,符号位是1,也就是-2^32(我们可以看到的)
1000 0000 - 0000 0001 = 0111 1111 ,计算机存储的是0111 1111,最高位符号位是0,正数,2^32 -1


编辑于 2022-04-11 12:52:13 回复(0)
编译了一下.确实死循环了
发表于 2022-03-01 16:55:24 回复(0)
a+b会一直等于1,就算是溢出也是成立的,至于用char来分析,应该是不合适的,char没有正负,最高位是保留用于IBM计算机的。
发表于 2021-11-01 14:50:44 回复(0)
b=1-a mod 2n a+b = 1 mod 2n && a+b <- [-n,n) 得 a+b=1
发表于 2021-10-07 20:29:02 回复(0)
#include <iostream>
using namespace std;
void main()
{
char x,y,z;
x=128;
y=-127;
z=x+y;
cout<<(int)x<<endl<<(int)y<<endl<<(int)z<<endl;//-128,-127,1
system("pause");
}
运行以上代码,输出为-128,-127,1
发表于 2020-03-08 21:43:12 回复(1)
a+b永远等于1,死循环
发表于 2020-03-06 00:55:44 回复(0)
程序会运行到A那一步,但是数值溢出跟循环没关系,还是会继续循环下去。
发表于 2019-09-14 02:02:21 回复(0)

32位有些绕,那么可以用8位来简化分析


发表于 2019-03-16 21:00:07 回复(0)
以char为例 f(1,0):         a=2  b=-1         a=3  b=-2         ......         a=127 b=-126         a=128 b=-127  溢出-->a=-128 b=-127     char范围:-128~127         return a+b:-128-127实际上是1(char范围),继续循环 而原例为int_32t,临界情况 a+b:      -2^32+(-2^32+1)=1,也继续循环。 因此死循环。
发表于 2018-12-08 11:25:02 回复(0)
#include<stdio.h>
int main()
{

  char c=-129;
  printf("c=%d\n",c);

}

                 
[luoyiran@luoyiran ~]$ gcc yichu2.c -o yichu2
yichu2.c: 在函数‘main’中:
yichu2.c:5: 警告:隐式常量转换溢出
[luoyiran@luoyiran ~]$ vim yichu2.c
#include<stdio.h>
int main()
 { char c=-128;
  printf("c=%d\n",c);
  }


[luoyiran@luoyiran ~]$ ./yichu2
c=-128
#include<stdio.h>
int main()
{
  char c=127;
  printf("c=%d\n",c);
}


[luoyiran@luoyiran ~]$ ./yichu
c=127
#include<stdio.h>
int main()
{
  char c=128;
  printf("c=%d\n",c);
}

[luoyiran@luoyiran ~]$ ./yichu
c=-128

发表于 2018-08-11 12:36:36 回复(0)
以char类型为例 1 0 . . 127 -126 a+b =1 -128 -127 -128补码:1000 0000 -127补码: 1000 0001 a+b=1; 继续循环: -128补码:1000 0000 1补码:0000 0001 a=-127; 0000 0001 a=-126 -127补码:1000 0001 -1补码: 1111 1111 b= -128; a+b =1; 1111 1111 b= 127 ; a+b =1
发表于 2018-08-09 11:08:49 回复(0)