62,635
社区成员




String binary="11000000101010000000000100000001";
int ipnum = Integer.parseUnsignedInt(binary,2);
System.out.println(ipnum);
String binary="11000000101010000000000100000001";
int ipnum = Integer.parseInt(binary,2);
System.out.println(ipnum);
public static int parseUnsignedInt(String s, int radix)
throws NumberFormatException {
if (s == null) {
throw new NumberFormatException("null");
}
int len = s.length();
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar == '-') {
throw new
NumberFormatException(String.format("Illegal leading minus sign " +
"on unsigned string %s.", s));
} else {
if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits
(radix == 10 && len <= 9) ) { // Integer.MAX_VALUE in base 10 is 10 digits
return parseInt(s, radix);
} else {
long ell = Long.parseLong(s, radix);
if ((ell & 0xffff_ffff_0000_0000L) == 0) {
return (int) ell;
} else {
throw new
NumberFormatException(String.format("String value %s exceeds " +
"range of unsigned int.", s));
}
}
}
} else {
throw NumberFormatException.forInputString(s);
}
}
注意这两句:
long ell = Long.parseLong(s, radix);
if ((ell & 0xffff_ffff_0000_0000L) == 0) {
return (int) ell;
} else {
throw new
NumberFormatException(String.format("String value %s exceeds " +
"range of unsigned int.", s));
}
这里,首先进行parseLong,因为你的二进制数据是32位,没有导致溢出,所以这句会返回3232235777
但是,这个数字已经是超出Int的表示范围了,所以在执行
(int) ell //(int)3232235777L
强转时,就发生了溢出,结果就是负的了。(具体的原理就不说了,lz可以百度java数值类型转换溢出处理)
给个传送门吧:
http://blog.csdn.net/u011637069/article/details/46786679
public static int parseUnsignedInt(String s, int radix)
throws NumberFormatException {
if (s == null) {
throw new NumberFormatException("null");
}
int len = s.length();
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar == '-') {
throw new
NumberFormatException(String.format("Illegal leading minus sign " +
"on unsigned string %s.", s));
} else {
if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits
(radix == 10 && len <= 9) ) { // Integer.MAX_VALUE in base 10 is 10 digits
return parseInt(s, radix);
} else {
long ell = Long.parseLong(s, radix);
if ((ell & 0xffff_ffff_0000_0000L) == 0) {
return (int) ell;
} else {
throw new
NumberFormatException(String.format("String value %s exceeds " +
"range of unsigned int.", s));
}
}
}
} else {
throw NumberFormatException.forInputString(s);
}
}
看到这个return (int) ell; 了吧,它是由long转化来的,也就是它还是默认32位的左起第一位是符号位,1就是负,0就是正。
public static int parseInt(String s, int radix)
throws NumberFormatException
{
/*
* WARNING: This method may be invoked early during VM initialization
* before IntegerCache is initialized. Care must be taken to not use
* the valueOf method.
*/
if (s == null) {
throw new NumberFormatException("null");
}
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
}
if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix +
" greater than Character.MAX_RADIX");
}
int result = 0;
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
int multmin;
int digit;
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')
throw NumberFormatException.forInputString(s);
if (len == 1) // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
i++;
}
multmin = limit / radix;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++),radix);
if (digit < 0) {
throw NumberFormatException.forInputString(s);
}
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result;
}
lz代码在1.8下,会在
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
这行出错。
下面来分析分析为什么会在这行出错。
通过上面贴出来的代码,不难发现,parseInt的过程起始很简单,首先判断第一个字符是不是“+或者-”如果是"-",则说明值是负的,否则,值就是正的。
好,这个逻辑在非二进制环境下没有问题,因为非二进制表示的int变量,都是会用“-”来表示负数。
然而,在二进制条件下,符号位的影响就出来了,因为二进制不是通过“+,-”来区分正负,而是通过第一位“是1还是0”来判断正负。所以,在parseInt时,由于将符号位也当做实际的值计算进去了,所以就导致计算溢出,出错了。。。。
解决办法就是把二进制的第一位的“0,1”改成“-,+”,就可以了:
public static void main(String[] args) {
String binary = "+1000000101010000000000100000001"; // 11000000101010000000000100000001
int ipnum = Integer.parseInt(binary, 2);
System.out.println(ipnum);
binary = "-1000000101010000000000100000001"; // 01000000101010000000000100000001
ipnum = Integer.parseInt(binary, 2);
System.out.println(ipnum);
}
if (firstChar == '-') {
throw new
NumberFormatException(String.format("Illegal leading minus sign " +
"on unsigned string %s.", s));
}
去看代码呀