java - 按位运算意外变为负数

标签 java bit-manipulation

有人可以向我解释为什么我会得到这些结果吗?

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("10.35.41.134"),我得到:

shift = 0
result = 10
shift = 2560
result = 2595
shift = 664320
result = 664361
shift = 170076416
result = 170076550
10.35.41.134 = 170076550

这与我自己计算得到的结果相同。

对于 ipv4ToInt("192.168.0.1"),我得到:

shift = 0
result = 192
shift = 49152
result = 49320
shift = 12625920
result = 12625920
shift = -1062731776
result = -1062731775
192.168.0.1 = -1062731775

对于这个,当我手动计算时,我得到 3232235521。

有趣的是:
3232235521 = 11000000101010000000000000000001
当我在我的 Windows 计算器中输入 1062731775 并点击 +/- 按钮时,我得到:
-1062731775 = 11111111111111111111111111111111 11000000101010000000000000000001

该函数仍然适用于我的目的,但我真的很想知道为什么在我执行最后一个位移位时结果会变为负值?

最佳答案

因为您的情况发生位溢出!

在Java中,整数也是32位的,取值范围是-2,147,483,648到2,147,483,647。

12625920 << 8超过了 2^31-1 的极限,结果变成了负数...

结果刚好从 -ve 侧翻转,因此,从正侧剩下的任何范围都伴随着负侧的那么多!!!

按照大家的建议,你应该使用long避免溢出的变量!

关于java - 按位运算意外变为负数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25918757/

相关文章:

java - 多线程将图像添加到表面 View 中

java - 构建 Apache Spark 时出错

c - 按位运算还实用吗?

sql - 查找给定日期范围、持续时间和不可用日期列表的可用公寓

Java - Tree 是 Node 的一个实例吗?

java - doClick() 是否需要启用组件?

java - 有没有办法远程查看 Swing 应用程序?

Javascript - 打开位

c# - 反转位移运算符/2 的幂

c - 128 位整数之间的按位运算