Java的字符串转int算法
2018-09-29 04:03:02来源:博客园 阅读 ()
面T家,被要求实现一个字符串转整型数的算法,当时手写有点遗漏,现在回头来看看jdk的实现。
常用的是Integer.valueOf方法来实现转换:
1 public static Integer valueOf(String s) throws NumberFormatException { 2 return Integer.valueOf(parseInt(s, 10)); 3 }
默认会调用parseInt方法进行转换,参数中的10说明是按照10进制进行转换的。
看看parseInt方法:
1 public static int parseInt(String s, int radix) 2 throws NumberFormatException 3 { 4 5 if (s == null) { 6 throw new NumberFormatException("null"); 7 } 8 9 if (radix < Character.MIN_RADIX) { 10 throw new NumberFormatException("radix " + radix + 11 " less than Character.MIN_RADIX"); 12 } 13 14 if (radix > Character.MAX_RADIX) { 15 throw new NumberFormatException("radix " + radix + 16 " greater than Character.MAX_RADIX"); 17 } 18 19 int result = 0; 20 boolean negative = false; 21 int i = 0, len = s.length(); 22 int limit = -Integer.MAX_VALUE; 23 int multmin; 24 int digit; 25 26 if (len > 0) { 27 char firstChar = s.charAt(0); 28 if (firstChar < '0') { // Possible leading "+" or "-" 29 if (firstChar == '-') { 30 negative = true; 31 limit = Integer.MIN_VALUE; 32 } else if (firstChar != '+') 33 throw NumberFormatException.forInputString(s); 34 35 if (len == 1) // Cannot have lone "+" or "-" 36 throw NumberFormatException.forInputString(s); 37 i++; 38 } 39 multmin = limit / radix; 40 while (i < len) { 41 // Accumulating negatively avoids surprises near MAX_VALUE 42 digit = Character.digit(s.charAt(i++),radix); 43 if (digit < 0) { 44 throw NumberFormatException.forInputString(s); 45 } 46 if (result < multmin) { 47 throw NumberFormatException.forInputString(s); 48 } 49 result *= radix; 50 if (result < limit + digit) { 51 throw NumberFormatException.forInputString(s); 52 } 53 result -= digit; 54 } 55 } else { 56 throw NumberFormatException.forInputString(s); 57 } 58 return negative ? result : -result; 59 }
首先看到5-17行是边界检查:
- 如果字符串s是空指针,直接抛异常
- 如果进制小于最小进制(常量定义为2),抛异常
- 如果进制大于最大进制(常量定义为36),抛异常
接下来19-24行是局部变量定义,这里需要注意一个就是limit被赋值为int表示的最大正整型数的负值,也就是-2147483647。
再往下看到26-38行,如果字符串s长度大于0,那么首先看看首字符
- 如果首字符小于字符0,那么可能是符号 + 或者 - ,要区别对待了
- 如果是符号 - ,说明是个负数,将布尔值变量negative设置为true,并将limit设置为int型整数的下限值,也就是-2147483648
- 如果首字符不是符号 +,说明首字符既不是数字也不是符号,则抛出异常
- 再接下来看,如果首字符是符号 - 或者 +,但是字符串长度只有1,也就是说只有一个符号,那么也是不能够转为整型数的,直接抛异常
再往下39-54行
局部变量mulmin赋值为limit除以当前转换的进制。接下来是一个循环,i代表处理的字符串的位数。
用局部变量digit记录字符串s第i位数字的相应进制的值,接下来又是一些判断了:
- 如果digit小于0,抛异常
- 如果result变量小于mulmin,抛异常,这里可以限制之后的乘法操作肯定不溢出;之后result变量乘以当前转换进制。(如果result小于mulmin也就是limit/radix了,那么后面的乘以radix肯定就会小于limit,对于负数就超过了Integer的范围,对于正数也是超过了Integer.MAX_VALUE)
- 如果此时result小于limit加上digit,抛异常,这里可以限制之后的减法操作不会溢出;之后result变量减去digit的值。(这个抛异常和上一条原因类似,也是为了防止溢出)
最后58行,如果negative为true,则直接返回result,否则返回负的result。
这个有点意思,如果是负数直接输出,如果是正数反而是用负数取负,负负得正来表示的。
个人觉得应该是整型数从绝对值来看,负数的范围比正数大1,如果用result += digit这样来进行计算的话,那么最小值-2147483648会无法被正确转换。因为2147483640+8会得到-2147483648,然后再取负数的话,就变成0了。但是使用-=来计算,因为负数的范围更大,因此正数是可以全部表示出来的,而且不管是+0还是-0都不会有问题,都可以得到数值0。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:我又回来了
- 国外程序员整理的Java资源大全(全部是干货) 2020-06-12
- 2020年深圳中国平安各部门Java中级面试真题合集(附答案) 2020-06-11
- 2020年java就业前景 2020-06-11
- 04.Java基础语法 2020-06-11
- Java--反射(框架设计的灵魂)案例 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash