ArithmeticException 不会因 2^32 内的溢出而抛出
ArithmeticException not thrown for overflow within 2^32
我知道分配一个大于 2^32
的数字有机会生成一个 ArithmeticException
但今天我在编程时:
int x = 65535
System.out.println(x * x);
Output: -131071
所以没有例外,只是意外的结果。
溢出
乘法不受保护防止溢出。
你在这里看到的是整数溢出。如果你取最大的整数 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
In Java int
是一个带符号的 32 位值。特别是 not 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
时才会发生这种情况,因为根据定义这是不可能的。另请参阅异常的 documentation。
对于受保护的乘法,请考虑使用 Math#multiplyExact
(documentation)。
我认为您对 int 类型有多少位感到困惑,它是 32 位到它代表的数字之间:
-2 147 483 648 <= int <= 2 147 483 647
因为它也代表负数,所以只能代表2^31
在java中,int是原始的带符号的32位,它有
max value = 2.147.483.647
和
min value = -2.147.483.648
你的乘法结果是 4.294.836.225。
因为你使用 int 基本类型,如果它 overflows
,它会回到 minimum value
并从那里继续。如果它 underflows
,它会返回到 maximum value
并从那里继续。
如果你想捕获异常,你可以使用Math
class 或 Integer
class.
try
{
int c = Math.multiplyExact(a,b);
} catch (ArithmeticException ex)
{
System.err.println("int is too small, falling back to long.");;
}
我知道分配一个大于 2^32
的数字有机会生成一个 ArithmeticException
但今天我在编程时:
int x = 65535
System.out.println(x * x);
Output: -131071
所以没有例外,只是意外的结果。
溢出
乘法不受保护防止溢出。
你在这里看到的是整数溢出。如果你取最大的整数 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
In Java int
是一个带符号的 32 位值。特别是 not 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
时才会发生这种情况,因为根据定义这是不可能的。另请参阅异常的 documentation。
对于受保护的乘法,请考虑使用 Math#multiplyExact
(documentation)。
我认为您对 int 类型有多少位感到困惑,它是 32 位到它代表的数字之间:
-2 147 483 648 <= int <= 2 147 483 647
因为它也代表负数,所以只能代表2^31
在java中,int是原始的带符号的32位,它有
max value = 2.147.483.647
和
min value = -2.147.483.648
你的乘法结果是 4.294.836.225。
因为你使用 int 基本类型,如果它 overflows
,它会回到 minimum value
并从那里继续。如果它 underflows
,它会返回到 maximum value
并从那里继续。
如果你想捕获异常,你可以使用Math
class 或 Integer
class.
try
{
int c = Math.multiplyExact(a,b);
} catch (ArithmeticException ex)
{
System.err.println("int is too small, falling back to long.");;
}