首先要知道的是int的取值范围,integer占4个字节,即32位。(一个字节,占8位)
0111 1111 1111 1111 1111 1111 1111 1111 (最高位表示符号位,正数符号位为0)对应的10进制数为2^31-1=2147483647,对应的十六进制表示为:0x7FFFFFFF
对剩下的位取反,结果为 1111111 11111111 11111111 11111111,加一后为10000000 00000000 00000000 00000000
所以int的取值范围为:【 -2^31,2 ^31-1】,即-2147483648~2147483647
至于关键的越界问题,评论里有个有意思的解答是
public int reverse(int x)
{
int result = 0;
while (x != 0)
{
int tail = x % 10;
int newResult = result * 10 + tail;
if ((newResult - tail) / 10 != result)
{ return 0; }
result = newResult;
x = x / 10;
}
return result;
}
其中(newResult-tail) / 10 != result
,经过一个简单的测试我们可以知道INT_MAX+1
输出的结果是-2147483648,代表着最小的int值,这样的话代码的确跑的通,但是本质上却是错误的解答(待证)
有一个比较合乎常规的做法
class Solution {
public int reverse(int x) {
long res = 0;
while (x != 0) {
res *= 10;
res += x % 10;
x /= 10;
}
return (int)res == res ? (int)res : 0;
}
}
其采用了8字节的long来保存result 避免了越界后结果改变的问题
若遇到int类型的需要倒序输出的题目或者是#9回文(指的是正序和倒序一样的数字,如1221)类型的题目,都可以使用本题的思路:
- 用10求余求出尾数
- 之前累加的结果乘10加当前尾数
- int值除10
- 循环直到余数为零