【发布时间】:2012-08-03 12:13:17
【问题描述】:
我是一名 Java 初学者,对此很困惑。
System.out.println(4*2147483647)在java中如何等于-4?
【问题讨论】:
标签: java
我是一名 Java 初学者,对此很困惑。
System.out.println(4*2147483647)在java中如何等于-4?
【问题讨论】:
标签: java
这是由于整数静默溢出。
2147483647 == Integer.MAX_VALUE 是整数的最大值。
静默溢出意味着2147483647 + 1 == Integer.MIN_VALUE = -2147483648
然后可以看到2147483647 + 2147483647 == 2147483647 + (-2147483648 + - 1) == -2
换句话说,2147483647 * 2 == -2,你现在可以明白为什么2147483647 * 4 == -4了。
从技术上讲,结果由Java Language Specification #15.17.1 定义:
如果整数乘法溢出,则结果是数学乘积的低位,以某种足够大的二进制补码格式表示。因此,如果发生溢出,则结果的符号可能与两个操作数值的数学乘积的符号不同。
【讨论】:
这与处理器执行二进制乘法的方式有关。你在那里的数字是最大的有符号整数,表示为0111111111111111111111111(我没有检查那里的数字,但我想你明白了)。
当你乘以 4 时,就像左移 2 一样,结果是 11111111111111111111100(代表 -4)。您可能想阅读how mutiplication is done in binary。
【讨论】:
因为结果超出了int 的范围。
Primitive Data Types
要解决此问题,请使用long 而不是int。
【讨论】:
问题是您使用的是 int(4 个字节)而不是 long(8 个字节)
System.out.println(4*2147483647);
尝试在其中一个数字后添加一个 l(用于 lema),以使结果为 long 而不是 Integer。整数的最大值小于您的结果 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
【讨论】:
计算机系统中的大多数整数基于 32 位,即 4 字节(您也可以使用 64 位或更多)。在 32 位整数中最多可以有 4,294,967,295。所以 4,294,967,295 + 5 会导致溢出给你 5。另外 -1 表示整数 4,294,967,295。因为有一个负位。
【讨论】:
这是因为计算机如何在内存中存储数字。 2147483647 * 4 = 8589934588
8589934588 二进制结果为 1 1111 1111 1111 1111 1111 1111 1111 1100
第一个是位,表示它前面的数字是负数。
下一部分可以用补码来解释。
二进制补码是一种表示负值的方法,它通过将所有位取反然后加一个来计算。 这将导致 0011(最后 4 个字节的反转),然后添加一个导致它是 0100,这是 4 的二进制表示。
因为符号位为负,所以结果为-4
【讨论】: