最近做了一道题目:
Given a 32-bit signed integer, reverse digits of an integer.
Example 1:
Input: 123
Output: 321
Example 2:
Input: -123
Output: -321
Example 3:
Input: 120
Output: 21
Note:
Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [?231, 231 ? 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.
来源:https://leetcode.com/problems/reverse-integer/
先贴上自己丑陋的代码:
1 classSolution {2 public:3 int reverse(intx) {4 bool isNegative=false;5 if(x==0||xpow(2,31)-1)6 return 0;7 if(x<0){8 isNegative=true;9 x=-1*x;10 }11 while(x%10==0)12 x=x/10;13 int ans=0,temp;14 temp=x-(x/10)*10;15 while(x>=1&&ans=1)22 return 0;23 if(isNegative)24 ans=ans*(-1);25 returnans;26 }27 };
(单从速度角度来看,好像还可以?).

但是看到了讨论区一个意大利大佬的代码,确实是short and element:
1 public int reverse(intx) {2 int prevRev = 0 , rev= 0;3 while( x != 0){4 rev= rev*10 + x % 10;5 if((rev - x % 10) / 10 !=prevRev){6 return 0;7 }8 prevRev =rev;9 x= x/10;10 }11 returnrev;12 }
不像我傻傻地用pow判断溢出,这段代码的判定语句很特别:
if((rev - x % 10) / 10 !=prevRev){
return 0;
我放到vs里测试了一下,打印了结果出来。
测试代码:
cout << rev <
rev= rev * 10 + x % 10;
cout<< "afterchange:" << rev << endl;
结果:
关键是最后一行,应该是9646324351的结果变成了1056389759.这应该就是Int溢出的结果。
通过查找网络资料,看到有一个答案说的是对的(https://zhidao.baidu.com/question/1899917410883143460.html?qbl=relate_question_0&word=C%2B%2B%20Int%D4%CB%CB%E3%B3%AC%B3%F6%B7%B6%CE%A7)
C语言int占4个字节,一共32位,范围是-2147483648 ~ 2147483647。
如果超出这个范围,就会加上或减去4294967296,使得值还落在这个范围内。
比如定义int变量a的值为2147483647,再加1就是2147483648,超出范围,因此需要减掉4294967296,最后打印的值就是-2147483648
实际上,1056389759就是9646324351-2*4294967296.也就是减去了两倍的“模长”。不像一开始就输入一个超出Int范围的整数时的情况,编译器不会发现超出范围、不会报错(因为这更像一个逻辑错误,是运行中产生的),只会在运行的过程中通过“减模长”的形式使其在范围内。所以,之后判断Int超出时,可以使用一个整数来配合检查,其的作用是保存变换之前的整数,以此和变换后的整数通过变换公式来检查变换是否正确,如果变换发生了异常,则说明超出了范围。当然,也可以通过一个Long来保存正确结果,通过和这个Long的数值比较来确定有没有出现问题。但是这样的话好像就没有太大意义了(笑~)