【问题标题】:Why does this multiplication integer overflow result in zero?为什么这个乘法整数溢出导致零?
【发布时间】:2015-08-17 03:26:22
【问题描述】:

在回答this question 后,我很困惑为什么这段代码中溢出的整数会导致0 而不是负数。奇怪,为什么会有这么精确的数字?为什么是 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

【问题讨论】:

    标签: java integer-overflow


    【解决方案1】:

    这只会在x 的起始值是偶数时发生。

    根据JLS §15.17.1

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

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

    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 的起始值为奇数,我们看不到这些尾随零。相反,它会导致看似不相关的数字,就像溢出通常那样。

    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
    

    【讨论】:

    • 所以如果起始数字是奇数,它会产生 1 还是负数?
    猜你喜欢
    • 2018-07-10
    • 2011-12-07
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    • 2018-10-11
    相关资源
    最近更新 更多