为什么Integer.MAX_VALUE * 2返回-2?

时间:2018-12-05 19:45:03

标签: java integer

我一直在寻找值i,其中i==i+1应该始终为true。其他一些人使用doublefloat来找到问题的解决方案。

我试图回答有关堆栈溢出的问题。然后考虑整数,尝试看看是否也有可能。

但是在多次操作Integer.MAX_VALUEInteger.MIN_VALUE时,我发现了这种奇怪的行为:

Integer.MAX_VALUE + 1 == Integer.MIN_VALUE

但是Integer.MAX_VALUE * 2 == -2Integer.MAX_VALUE * 4 == -4

仅当我使用偶数(2,4,6,8,10,12 ...)时才会发生这种情况。当我使用 1 以外的奇数值时,会发生这种情况:

Integer.MAX_VALUE * n == Integer.MAX_VALUE - n + 1,其中n != Integer.MIN_VALUEn > Integer.MIN_VALUE

为什么这样?我有什么想念的吗?

编辑:我看到有人将问题标记为重复,但导航到引用的链接,我的问题有所不同。

  

如果溢出,则返回最小值并从那里继续。如果下溢,则返回最大值并从那里继续>

我从那里仔细阅读了答案,但没有一个解释原因:

如果 x 是偶数,则

Integer.MAX_VALUE*x应该是-x,如果 y Integer.MAX_VALUE*y应该是Integer.MAX_VALUE-y+1是一个奇数。

这正是让我最困惑的地方。

2 个答案:

答案 0 :(得分:2)

这是因为Java的有符号整数遵循two's complement表示形式。

在二进制补码表示形式中,负数表示为其相应正值的一个 N complement ,即它们的总和模2 n 为0。

Integer.MAX_VALUE2147483647(十六进制0x7FFFFFFF)。 当相乘时,它溢出,剩下的是最低的32位(即模2 32 ):

0x7FFFFFFF * 2 = 0x0FFFFFFFE (mod32 = 0xFFFFFFFE = -2)
0x7FFFFFFF * 3 = 0x17FFFFFFD (mod32 = 0x7FFFFFFD = 2147483645)
0x7FFFFFFF * 4 = 0x1FFFFFFFC (mod32 = 0xFFFFFFFC = -4)
0x7FFFFFFF * 5 = 0x27FFFFFFB (mod32 = 0x7FFFFFFB = 2147483643)
0x7FFFFFFF * 6 = 0x2FFFFFFFA (mod32 = 0xFFFFFFFA = -6)
0x7FFFFFFF * 7 = 0x37FFFFFF9 (mod32 = 0x7FFFFFF9 = 2147483641)

二进制补码表示法的一个有趣特性是,最高位对应于该值的 sign

请注意最左边的7如何产生交替的0/1位31。该位恰好控制结果的符号,因此也控制交替的符号。

为什么0x7FFFFFFF * 2-2是因为0x7FFFFFFF在31位表示形式(最大可能的表示形式,没有溢出)中是-1。 -1 * 2 = -2。

如果采用Long.MAX_VALUE并将结果转换为int,则可以获得类似的结果:

long x = Long.MAX_VALUE;
for (int i = 2; i < 8; i++) {
    System.out.println((int)(x * i));
}

只需打印:

-2
-3
-4
-5
-6
-7

现在第31位不再交替显示,因此我们获得了稳定的结果。

答案 1 :(得分:1)

2147483647是最大值,现在尝试执行以下指令集:

int i = 2147483647;
i++;
System.out.println(i);//prints -2147483647 as the 32 bit limit exceeds 

2147483647的二进制等效值为01111111111111111111111111111111111
2的二进制等效项是00000000000000000000000000000010

二进制加法为110000000000000000000000000000000

注意:左侧的最后一位代表符号,int是32位有符号整数

因此,数字变为-2147483647

i++;
System.out.println(i); // prints -2147483647

在同一行上,2147483647 * 2实际上是-> 2147483647 + 2147483647

int j = 2147483647;
j += 2147483647;
System.out.println(j); // prints -2

,然后您回答。 现在,当您执行2147483647 * 3时,

是:

2147483647 + 2147483647 + 2147483647 = -2 + 2147483647 = 2147483645