数据类型相关问题?

整笔记时发现了个挺奇怪的问题 (Java 版本是 17)

首先, int 类型的取值范围是 -2147483648 ~ 2147483647
那么, 如果我定义一个这样的值, 在通过运算突破极值范围, 那他还是个 int 类型吗?
于是我试着写了这样一段代码

public static void main(String[] args) {
    int num = 2147483647;
    int numGreater = num * 2;
    System.out.println(numGreater); // -2
}

这个问题没有什么实际的意义, 只是纯好奇
有没有大佬知道, numGreater 的值为什么会等于 -2 ?

public static void main(String[] args) {
    int num = 2147483647;
    int numGreater = num + 1;
    System.out.println(numGreater); // -2147483648
}

好像只要在极限的边缘做运算得出来的结果都挺奇怪的

阅读 1.5k
avatarAI BotBETA

首先,我们需要理解整数溢出(Integer Overflow)的概念。在Java(以及其他许多编程语言)中,整数溢出发生在整数数值超过了其类型所能表示的最大值或最小值时。这通常发生在加法、减法、乘法或除法运算中。

在你的第一个例子中:

public static void main(String[] args) {
    int num = 2147483647;
    int numGreater = num * 2;
    System.out.println(numGreater); // -2
}

num乘以2时,结果超过了int类型能表示的最大值,因此发生了溢出。Java在处理整数溢出时,会采用模数运算(Modular Arithmetic)的方式。这意味着当数值超过最大值时,它会从最小值开始重新计数。这就是为什么numGreater的值是-2。

在你的第二个例子中:

public static void main(String[] args) {
    int num = 2147483647;
    int numGreater = num + 1;
    System.out.println(numGreater); // -2147483648
}

num加1时,结果超过了int类型能表示的最大值,因此也发生了溢出。同样地,由于采用了模数运算,结果变成了int类型能表示的最小值。这就是为什么numGreater的值是-2147483648。

值得注意的是,Java提供了Integer.MAX_VALUEInteger.MIN_VALUE两个常量,分别表示int类型能表示的最大和最小值。如果你在代码中进行了可能导致溢出的运算,使用这些常量可以帮助你检测并处理这种情况。

2 个回答

muliplication expression *

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.

就是按照足够大的位数算一个精确结果,然后只取低位。

不同语言的规定会不太一样,所以要看语言自己的规定。

但是结果通常都是类似的,因为这样实现起来最方便。

新手上路,请多包涵

了解一下计算机是这么存储数据的

推荐问题
宣传栏