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

溢出

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

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

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

判断整数溢出

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

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

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

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

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

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

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

完整判断代码如下:

private boolean outOfRange(String str) {
int length = str.length();
if(length == 0){
return false;
}
int index = 0;
int sum = 0; // 记录累加结果
while(index < length) {
int digit = str.charAt(index) - '0';
// 这里假定str是合法的字符串,不需要进行digit合法性判断 if(Integer.MAX_VALUE/10 < sum || (Integer.MAX_VALUE/10 == sum && Integer.MAX_VALUE % 10 < digit)) {
// 说明溢出
return true;
}
// 说明还没有溢出
sum = sum * 10 + digit;
index ++;
}
return false;
}

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

LeetCode整数反转

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

package com.jiajia.m5;

import java.math.BigDecimal;

/**
* @ClassName: ReverseInteger
* @Author: fanjiajia
* @Date: 2019/5/17 下午8:00
* @Version: 1.0
* @Description:
*/
public class ReverseInteger { public static void main(String[] args) {
ReverseInteger r = new ReverseInteger();
System.out.print(r.reverse(1534236469));
} public int reverse(int x) {
if(x == 0) {
return 0;
}
char[] ch_arr = String.valueOf(x).toCharArray();
StringBuilder sb = new StringBuilder();
int end_index = ch_arr[0] == '-'? 1 : 0;
boolean flag = ch_arr[ch_arr.length - 1] == '0'; // 最后一位为0
for(int i = ch_arr.length - 1; i >= end_index; i--) {
if(flag && ch_arr[i] == '0') {
continue;
}
flag = false;
sb.append(ch_arr[i]);
}
/**
* 方案一:异常里面返回,也是够了
*/
// int result;
// try {
// result = end_index == 1? -Integer.valueOf(sb.toString()) : Integer.valueOf(sb.toString());
// }catch(NumberFormatException e) {
// return 0;
// }
// return result;
/**
* 方案二:转为BigDecimal
*/
// BigDecimal b = new BigDecimal(sb.toString());
// if(b.compareTo(new BigDecimal(String.valueOf(Integer.MAX_VALUE))) > 0) {
// return 0;
// }else{
// return end_index == 1? -Integer.valueOf(sb.toString()) : Integer.valueOf(sb.toString());
// } /**
* 方案3:做溢出判断
*/
if(outOfRange(sb.toString())) {
return 0;
}else {
return end_index == 1? -Integer.valueOf(sb.toString()) : Integer.valueOf(sb.toString());
}
} private boolean outOfRange(String str) {
int length = str.length();
if(length == 0){
return false;
}
int index = 0;
int sum = 0; // 记录累加结果
while(index < length) {
int digit = str.charAt(index) - '0';
// 这里假定str是合法的字符串,不需要进行digit合法性判断 if(Integer.MAX_VALUE/10 < sum || (Integer.MAX_VALUE/10 == sum && Integer.MAX_VALUE % 10 < digit)) {
// 说明溢出
return true;
}
// 说明还没有溢出
sum = sum * 10 + digit;
index ++;
}
return false;
}
}

有意思的是写了个溢出判断函数的效率还没有直接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. 大专生自学web前端到找到工作的经验

    先做个自我介绍,我13年考上一所很烂专科民办的学校,学的是生物专业,具体的学校名称我就不说出来献丑了.13年我就辍学了,我在那样的学校,一年学费要1万多,但是根本没有人学习,我实在看不到希望,我就退学 ...

  2. fastjson反序列化漏洞研究(上)

    前言 最近护网期间,又听说fastjson传出“0day”,但网上并没有预警,在github上fastjson库中也有人提问关于fastjson反序列化漏洞的详情.也有人说是可能出现了新的绕过方式.不 ...

  3. ipv4与ipv6 Inet4Address类和Inet6Address类

    在设置本地IP地址的时候,一些人会疑惑IPv4与IPv6的区别是什么?下面由学习啦小编为你分享ipv4与ipv6的区别的相关内容,希望对大家有所帮助. ipv4与ipv6的区别 在windows 7以 ...

  4. Linux命令——expr

    前言 有时,在处理命令行时(特别是在处理shell脚本时),您可能会发现自己处于必须执行搜索字符串中的子字符串,查找其索引以及其他内容,或者执行比较和算术运算等情况.上述问题expr都能帮我们解决. ...

  5. BIOS+MBR操作系统引导方式

    1. 主引导记录(Master Boot Record,缩写:MBR) 主引导记录又叫做主引导扇区,是计算机开机后启动操作系统时所必须要读取的硬盘首个扇区,它在硬盘上的三维地址为(柱面,磁头,扇区)= ...

  6. 用Jmeter做性能测试,之后报表展示

    https://octoperf.com/blog/2017/10/19/how-to-analyze-jmeter-results/ 看到性能测试平台的开发,我在想需要什么功能,报表需要什么样子的 ...

  7. SpringBoot之多数据源动态切换数据源

    原文:https://www.jianshu.com/p/cac4759b2684 实现 1.建库建表 首先,我们在本地新建三个数据库名分别为master,slave1,slave2,我们的目前就是写 ...

  8. 2. kafka

    目录: 1.kafka概念 2.kafka使用场景 3.相关术语 4.原理解析 5.项目实战 一. kafka是什么 https://www.jianshu.com/p/014af2b34159 Ka ...

  9. Python离线断网情况下安装numpy、pandas和matplotlib等常用第三方包

    联网情况下在命令终端CMD中输入“pip install numpy”即可自动安装,pandas和matplotlib同理一样方法进行自动安装. 工作的电脑不能上外网,所以不能通过直接输入pip命令来 ...

  10. EntityFramework 两个参数连续(中间有空格)问题

    昨天在项目中,用到 EntityFramework 通过SQL语句查询. 具体的SQL语句如下: SELECT t.* FROM ( SELECT c.id AS CommunityId, c.`na ...