为什么这个乘法整数溢出会导致零? [英] Why does this multiplication integer overflow result in zero?

查看:340
本文介绍了为什么这个乘法整数溢出会导致零?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在回答这个问题后,我对此代码中溢出的整数导致 0 而不是负数。这很奇怪,为什么这么准确?为什么是0?

After answering this question, I was confused about why the overflowing integer in this code resulted in 0 instead of a negative number. It's strange, why such an exact number? Why 0?

public class IntegerOverflow {
  public static void main(String[] args) {
    int x = 10;

    int i = 0;
    for (i = 0; i <= 5; i++)
    {
      x = x * x;
      System.out.println(x);
    }
  }
}

输出:

100
10000
100000000
1874919424
0
0


推荐答案

只有在的起始值时才会发生这种情况x 是偶数。



根据JLS§15.17.1


如果整数乘法溢出,则结果是数学乘积的低阶位,如某些足够大的二进制补码格式所示。因此,如果发生溢出,则结果的符号可能与两个操作数值的数学乘积的符号不同。

If an integer multiplication overflows, then the result is the low-order bits of the mathematical product as represented in some sufficiently large two's-complement format. As a result, if overflow occurs, then the sign of the result may not be the same as the sign of the mathematical product of the two operand values.

如果我们以二进制格式而不是十进制格式打印数字,这会更加明显:

This is made much more obvious if we print the numbers in binary format instead of in decimal:

public class IntegerOverflow {
  public static void main(String[] args) {
    int x = 10;

    int i = 0;
    for (i = 0; i <= 5; i++)
    {
      x *= x;
      System.out.println(Integer.toBinaryString(x));
    }
  }
}

输出:

1100100
10011100010000
101111101011110000100000000
1101111110000010000000000000000
0
0

如您所见,每次平方时,我们将零位数加倍。由于只保存了低位,因此每次将零加倍最终将导致零。请注意,如果 x 的起始值为奇数,我们看不到这些尾随零。相反,它会导致看似无关的数字,例如溢出通常会发生。

As you can see, each time we square, we double the number of zero bits. Since only the low order bits are saved, doubling the zeroes every time will eventually result in zero. Notice that we do not see these trailing zeroes if the starting value for x is odd. It will result, instead, it will result in seemingly unrelated numbers like overflow usually does.

public class IntegerOverflow {
  public static void main(String[] args) {
    int x = 11;

    int i = 0;
    for (i = 0; i <= 5; i++)
    {
      x *= x;
      System.out.format("%-12d\t%s%n", x, Integer.toBinaryString(x));
    }
  }
}

输出:

121             1111001
14641           11100100110001
214358881       1100110001101101101101100001
772479681       101110000010110001101011000001
-1419655807     10101011011000011100010110000001
-1709061375     10011010001000011100101100000001

这篇关于为什么这个乘法整数溢出会导致零?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆