0

我知道分配一个大于2^32有机会生成ArithmeticException但今天我正在编程的数字:

int x = 65535
System.out.println(x * x);

Output: -131071

所以没有例外,但一个意想不到的结果。

4

3 回答 3

1

在 java 中,int 是原始有符号的 32 位,具有

最大值 = 2.147.483.647

最小值 = -2.147.483.648

你的乘法结果是 4.294.836.225。

由于您使用 int 原始类型,如果它overflows,它会返回minimum value并从那里继续。如果是underflows,它会回到maximum value并从那里继续。

如果你想捕获一个异常,你可以使用Math类或Integer类。

        try
        {
          int c = Math.multiplyExact(a,b);
        } catch (ArithmeticException ex)
        {
            System.err.println("int is too small, falling back to long.");;
        }
于 2018-05-13T15:45:14.143 回答
1

溢出

乘法不受溢出保护。

你在这里看到的是整数溢出。如果你取最大的整数Integer.MAX_VALUE并相加1,你会得到最小的整数INTEGER.MIN_VALUE

int value = Integer.MAX_VALUE;
System.out.println(value);  // 2147483647
value++;
System.out.println(value);  // -2147483648

同样的情况也发生在这里,因为

65_535 * 65_535 = 4_294_836_225 > 2_147_483_647

范围int

在 Javaint中是有符号的 32 位值。特别是,它不是 unsigned

                 |    min-value   |   max-value   |
-----------------|----------------|---------------|
   signed-32-bit |          -2^31 |      2^31 - 1 |
                 | -2_147_483_648 | 2_147_483_647 |
-----------------|----------------|---------------|
 unsigned-32-bit |        2^0 - 1 |      2^32 - 1 |
                 |              0 | 4_294_967_295 |

例外

乘法不会抛出ArithmeticException. 据我所知,这只有在除以 时才会发生0,因为根据定义,这不应该是可能的。另请参阅异常的文档

对于受保护的乘法,请考虑使用Math#multiplyExact文档)。

于 2018-05-13T15:40:47.617 回答
1

我认为您对 int 类型的32位与它所代表的数字之间的位数感到困惑:

 -2 147 483 648 <= int <= 2 147 483 647

因为它也代表负数,所以只能代表2^31

于 2018-05-13T15:41:36.700 回答