Integer.parseInt()小记(字符串转int)
字符串转int(Integer.parseInt()函数)
在牛客上看到一个字符串转int类型的题目,感觉看上去没什么难度,但是自己做的过程中,对于int越界判断做的较为复杂,翻看了Integer.parseInt()的源码之后,惊叹其清晰的逻辑判断。顺便吐槽下牛客网的测试用例中对于int类型越界判断有些问题,如图:
源码解读:
默认情况下,我们调用parseInt(String s)函数,其默认为十进制,转而调用parseInt(String s, int radix)方法。再次方法中先如下图所示,对字符串是否为空,进制是否小于2,或大于36进行了格式校验。
下面是函数中定义的变量:
result:用于记录中间结果及最终结果
negative:标志字符串表示的数字是否为负数
i:记录转换到了第几位,取值从0-len-1
len:记录字符串长度,
limit:记录结果边界,负数进行表示,能够简化在正负边界处绝对值差1的情况判断。(自己写的代码就没有考虑到这点,先求绝对值再加上符号,导致在MAX和MIN处的判断出现错误,无法输出MIN)
multmin:记录中间结果边界
digit:第i位上的字符转换为对应数字
接下来是对第一个字符进行判断,如果不是0-9数字,则根据是否为‘-’更改negative变量,如果negative为真,需要将limit设置为Integer.MIN_VALUE。并且对只有符号位的字符串进行异常抛出。最后,需要注意的是让i++,因为第一位已经转换了。
因为程序从将字符串从前向后进行转换,每转换一位需要进行上次结果乘上进制,加上本位数字两个操作,在这两个过程都需要进行越界判断
multmin=limit/radix:if (result < multmin)防止中间结果乘上进制后越界;如果不越界才会进行result *= radix;操作。
if (result < limit + digit) :这里判断了result加上本位数字后是否越界,如果不越界进行result-=digit;因为result一直为负数,所以是-=
这里需要格外注意
逻辑判断可以理解为if (result-digit < limit) (result一直未负数)。但是判断语句不能够这样书写,否则会出现类似下面的错误
错误产生原因是在下列判断语句中,由于result-digit已经越界:程序判断(-2147483640-9<limit),
此时limit=-2147483648,本该抛出异常。但是由于补码运算,导致result-digit计算后的补码为2147483647,使得判断条件假未能抛出异常。