有人可以向我解释为什么我会得到这些结果吗?
public static int ipv4ToInt(String address) {
int result = 0;
// iterate over each octet
for(String part : address.split(Pattern.quote("."))) {
// shift the previously parsed bits over by 1 byte
result = result << 8;
System.out.printf("shift = %d\n", result);
// set the low order bits to the current octet
result |= Integer.parseInt(part);
System.out.printf("result = %d\n", result);
}
return result;
}
对于ipv4ToInt(&#34; 10.35.41.134&#34;),我得到:
shift = 0
结果= 10
shift = 2560
结果= 2595
shift = 664320
结果= 664361
shift = 170076416
结果= 170076550
10.35.41.134 = 170076550
这与我自己进行数学运算时得到的结果相同。
对于ipv4ToInt(&#34; 192.168.0.1&#34;),我得到:
shift = 0
结果= 192
shift = 49152
结果= 49320
shift = 12625920
结果= 12625920
shift = -1062731776
结果= -1062731775
192.168.0.1 = -1062731775
对于这个,当我手动进行数学运算时,我得到3232235521。
有趣的是:
3232235521 = 11000000101010000000000000000001
当我输入1062731775进入我的Windows calc并点击+/-按钮时,我得到:
-1062731775 = 11111111111111111111111111111111 11000000101010000000000000000001
这个功能仍然可以用于我的目的,但是我真的好奇地知道为什么当我做最后一次移位时,地球上的结果会变为负面?
答案 0 :(得分:5)
因为你的情况下有点溢出!
在Java中,整数也是32位,范围是-2,147,483,648到2,147,483,647。
12625920 << 8
越过2 ^ 31-1的限制,因此结果变为负数......
结果只是从-ve侧翻了过来,因此,从积极方面留下的任何范围都伴随着来自消极方面的那么多!!!
正如大家所建议的,你应该使用long
变量来避免溢出!
答案 1 :(得分:1)
java中的所有原语都是签名的 - 它们可以是正面的也可以是负面的。最高位用于控制它,因此当它被设置时,数字变为负数。
尝试使用long代替 - 这将为您提供所需的结果,因为long可以更大,而不会出现溢出。
答案 2 :(得分:1)
11000000101010000000000000000001
是32位。它代表的值取决于你如何解释这些位:
Java使用有符号整数,因此如果您打印该值,您将看到一个负数。这并不意味着你的位错了。
答案 3 :(得分:0)
仅对打印很重要,您可以使用这些方法打印正整数:
1)将结果更改为long(java将为您完成工作)。
2)自己将signed int作为unsigned int处理(可能使方法为int2string(int n)或toString(int n)。
3)Integer.toUnsignedString(int)你正在使用java 8。
据我了解,你正在解析一个IP地址,记住,java使用签名数据类型,你不能有32位整数。
将结果更改为long以解决此问题。