Reverse Integer - Leetcode
2015-10-19 17:22
183 查看
题目补充要求:如果输入的int很大,经过逆转之后会有越界的可能。
例如:x = 1147483648,result = 8463847411,结果明显越界了,因此在这里我们需要对是否越界进行一个判断,如果越界则return 0。int表示数的范围是[-2147483648,2147483648)。
相关知识:见博文 计算机编码与变量范围
本题思路简单,但要注意判断是正是负。
(我觉得代码没问题啊,为什么不能通过。。)经过昨天笔者查看资料外加问大神同学,最后明白一二,现在总结一下问题以及改进办法。
1.在mian()函数中定义x=-2147483648(也就是-2^31),报错:C4146 一元负运算符应用于无符号类型,结果仍为无符号类型 。
虽然x是在int的表示范围内。由于编译器收到的源代码都是字符串形式的,-2147483648对于编译器是字面量,编译器看不懂字面量,需要将字面量转化成具体数值,因此编译器在翻译 “int x = -2147483648;” 这句源代码的时候,编译器的处理过程是这样的:
a. 提取 - 号
b.提取数字部分先翻译成一个正整数 temp
c. 将 - 号应用到 正整数 上,构成最后的结果
因此在mian()中定义 x=-2147483647-1或者-2147483646-2或者0x80000000就不会报错。
2.在x=-2147483648时,为什么y=-2147483648?
因为-2^31是一个比较特殊的数字,当你对它进行取负的时候(补码符号位不变,其余各位取反,最后加1),最后还是它本身。等于这个程序最后的K的符号还是和x一样,所以在判断是否越界时出现问题。将k >2147483648改成k<-2147483648,就可以AC。
第二种解决方式:
这里是先将x逐位分离,再改变正负号。长整数用16进制表示更为清晰直观。
补充:0x80000000=-2^31,0x80000001=-2^31+1(仍在范围之类,并不是表示越界的数。0x80000000一直+1就是将数字变大(因为是负数))
例如:x = 1147483648,result = 8463847411,结果明显越界了,因此在这里我们需要对是否越界进行一个判断,如果越界则return 0。int表示数的范围是[-2147483648,2147483648)。
相关知识:见博文 计算机编码与变量范围
本题思路简单,但要注意判断是正是负。
class Solution { public: int reverse(int x) { long long k=0; long long y=0;//这里之所以要定义一个long long型的,是因为在x=-2147483648时,取正会越界。 bool flag=x>0?true:false; if(flag==false) y=-x; else y=x; int i=10; while(y!=0) { k=k*10+y%i; y=y/i; } if(k>2147483647||(flag==false && k >2147483648)) return 0; //判断是否越界 if(flag==false) return (int)(-k); else return (int)k; } };
(我觉得代码没问题啊,为什么不能通过。。)经过昨天笔者查看资料外加问大神同学,最后明白一二,现在总结一下问题以及改进办法。
1.在mian()函数中定义x=-2147483648(也就是-2^31),报错:C4146 一元负运算符应用于无符号类型,结果仍为无符号类型 。
虽然x是在int的表示范围内。由于编译器收到的源代码都是字符串形式的,-2147483648对于编译器是字面量,编译器看不懂字面量,需要将字面量转化成具体数值,因此编译器在翻译 “int x = -2147483648;” 这句源代码的时候,编译器的处理过程是这样的:
a. 提取 - 号
b.提取数字部分先翻译成一个正整数 temp
c. 将 - 号应用到 正整数 上,构成最后的结果
unsigned int temp=2147483648; //b步(因为提取出的数值部分2^31超过int的表示范围,所以编译器用unsigned int 来存储) temp=-temp; //c步 (因为是用无符号数来存储数值的,所以对无符号数取负是错误的,因此会报错,报错发生在这一步) int n = temp; //c步
因此在mian()中定义 x=-2147483647-1或者-2147483646-2或者0x80000000就不会报错。
2.在x=-2147483648时,为什么y=-2147483648?
因为-2^31是一个比较特殊的数字,当你对它进行取负的时候(补码符号位不变,其余各位取反,最后加1),最后还是它本身。等于这个程序最后的K的符号还是和x一样,所以在判断是否越界时出现问题。将k >2147483648改成k<-2147483648,就可以AC。
第二种解决方式:
这里是先将x逐位分离,再改变正负号。长整数用16进制表示更为清晰直观。
int reverse(int x) { int num[32]; for (int i = 0; i < 32; i++) num[i] = 0; bool positive = x > 0 ? true : false; int j = 0; while (x != 0) { int digit = x % 10; num[j++] = positive ? digit : -digit; x = x / 10; } long long result = 0; int m = 0; while (m < j) { result = result * 10 + num[m++]; } if (positive == false && result>0x80000000) return 0; else if (positive&&result > 0x7fffffff) return 0; return positive ? result : -result; }
补充:0x80000000=-2^31,0x80000001=-2^31+1(仍在范围之类,并不是表示越界的数。0x80000000一直+1就是将数字变大(因为是负数))
相关文章推荐
- XML指南——XML编码
- C#中字符串编码处理
- ExtJS中文乱码之GBK格式编码解决方案及代码
- 程序员趣味读物 谈谈Unicode编码
- 文本文件编码方式区别
- C语言安全编码之数值中的sizeof操作符
- C#实现获取文本文件的编码的一个类(区分GB2312和UTF8)
- VC中BASE64编码和解码使用详解
- 计算机中的字符串编码、乱码、BOM等问题详解
- Base64编码解码原理及C#编程实例
- C#编码好习惯小结
- javascript编码的几个方法详细介绍
- UTF8编码开发中页面空白问题的解决方法
- php生成固定长度纯数字编码的方法
- 重新restore了mysql到另一台机器上后mysql 编码问题报错
- c# Base64编码和图片的互相转换代码
- java自动根据文件内容的编码来读取避免乱码
- PHP写入WRITE编码为UTF8的文件的实现代码
- 设置php页面编码的两种方法示例介绍
- js实现字符串的16进制编码不加密