我是一名Java初学者,对此很困惑。
java中如何System.out.println(4*2147483647)
等于-4?
这是由于整数静默溢出。
2147483647 == Integer.MAX_VALUE
是整数的最大值。
无声溢出意味着2147483647 + 1 == Integer.MIN_VALUE = -2147483648
您可以看到2147483647 + 2147483647 == 2147483647 + (-2147483648 + - 1) == -2
换句话说,2147483647 * 2 == -2
,你现在可以明白为什么了2147483647 * 4 == -4
。
从技术上讲,结果由Java 语言规范 #15.17.1 定义:
如果整数乘法溢出,则结果是数学乘积的低位,以某种足够大的二进制补码格式表示。因此,如果发生溢出,则结果的符号可能与两个操作数值的数学乘积的符号不同。
它与处理器执行二进制乘法的方式有关。你在那里的数字是最大的有符号整数,表示为0111111111111111111111111(我没有检查那里的数字,但我假设你明白了)。
当你乘以 4 时,就像左移 2 一样,结果是11111111111111111111100(代表 -4)。您可能想阅读二进制中的乘法是如何完成的。
因为结果超出了int
.
原始数据类型
要解决此问题,请使用 along
而不是int
.
问题是您使用的是 int (4 个字节)而不是 long (8 个字节)
System.out.println(4*2147483647);
尝试在其中一个数字之后添加一个 l(用于 lema),以便结果是长而不是整数。整数的最大值小于您的结果 http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Integer.html#MAX_VALUE
System.out.println(4l * 2147483647);
或者
System.out.println(4 * 2147483647l);
以上两个给出了正确的结果。那是 8589934588
这是因为计算机如何将数字存储在内存中。2147483647 * 4 = 8589934588
8589934588 二进制结果为 1 1111 1111 1111 1111 1111 1111 1111 1100
第一个是一个位,表示它前面的数字是负数。
下一部分可以用二进制补码来解释。
二进制补码是一种表示负值的方法,它通过将所有位取反然后加一个来计算。这将导致 0011(最后 4 个字节的反转),然后添加一个会导致它是 0100,这是 4 的二进制表示。
因为符号位为负,所以结果为 -4
计算机系统中的大多数整数基于 32 位,这意味着 4 字节(您也可以使用 64 位或更多)。在 32 位整数中最多可以有 4,294,967,295。所以 4,294,967,295 + 5 会导致溢出给你 5。另外 -1 表示整数 4,294,967,295。因为有一个负位。