简体   繁体   English

Java Integer.MIN_VALUE 的负数然后比较产生两个负数

[英]Java Integer.MIN_VALUE's negative then compare yields two negatives

I have a test tomorrow and I can't understand my books explanation, I appreciate the help:我明天要考试,我看不懂我的书的解释,我很感激帮助:

public class TestClass{
      public static void main(String[] args) throws Exception{
            int a = Integer.MIN_VALUE;
            int b = -a;
            System.out.println( a+ "   "+b);
      }
}

Output: -2147483648 -2147483648 Output: -2147483648 -2147483648

Why does this print 2 negative numbers of the same magnitude and not a positive and negative?为什么这会打印出 2 个大小相同的负数而不是正数和负数?

Because of silent integer overflow: Integer.MIN_VALUE is -2^31 and Integer.MAX_VALUE is 2^31-1 , so -Integer.MIN_VALUE is 2^31 , which is Integer.MAX_VALUE + 1 , which by definition is too large for an integer.由于无声整数溢出: Integer.MIN_VALUE-2^31并且Integer.MAX_VALUE2^31-1 ,所以-Integer.MIN_VALUE2^31 ,即Integer.MAX_VALUE + 1 ,根据定义对于一个整数。 So it overflows and becomes Integer.MIN_VALUE ...所以它溢出并变成Integer.MIN_VALUE ...

You can also check that:您还可以检查:

System.out.println(Integer.MAX_VALUE + 1);

prints the same thing.打印同样的东西。

More technically, the result is defined by the Java Language Specification #15.18.2 :从技术上讲,结果由Java 语言规范 #15.18.2 定义

If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format.如果整数加法溢出,则结果是数学和的低位,以某种足够大的二进制补码格式表示。 If overflow occurs, then the sign of the result is not the same as the sign of the mathematical sum of the two operand values.如果发生溢出,则结果的符号与两个操作数值的数学和的符号不同。

Basically, because Integer.MAX_VALUE is actually only 2147483647, so -Integer.MIN_VALUE , which would be +2147483648, actually overflows the capacity of the internal binary representation of integers.基本上,因为Integer.MAX_VALUE实际上只有 2147483647,所以-Integer.MIN_VALUE ,即 +2147483648,实际上溢出了整数内部二进制表示的容量。 Thus, the result "loops around" back to Integer.MIN_VALUE , or -2147483648.因此,结果“循环”回到Integer.MIN_VALUE或 -2147483648。

If you did long b = -((long)a);如果你做了long b = -((long)a); instead, you would get the expected result.相反,你会得到预期的结果。

To show this even more clearly:为了更清楚地表明这一点:

Integer.MIN_VALUE is -2^31 = -2147483648
Integer.MAX_VALUE is 2^31-1 = 2147483647 
/*notice this is 1 less than the negative value above*/

Integer.MAX_VALUE can not take 2147483648 . Integer.MAX_VALUE不能取2147483648 This is too large number for Integer by exactly 1. This causes the number to go back on the scale from max value back to starting poing which is the min value.这对于 Integer 来说太大了,正好是 1。这会导致数字从最大值回到起始点,即最小值。

A fixed number of binary bits can encode an even number of things.固定数量的二进制位可以编码偶数个东西。 That means that you can't have a sequence that's exactly centered on zero, since that would require an is number of things to be symmetrical.这意味着你不能有一个完全以零为中心的序列,因为这需要大量的东西是对称的。 The closest thing you can get to having zero in the middle of the sentence is to split it as either negative and non-negative, or positive and non-positive.在句子中间可以得到零的最接近的事情是将其拆分为负数和非负数,或正数和非正数。 Normal twos complement encoding does the former.正常二进制补码编码是前者。 So 32 bits span the range from -2^31 to 2^31-1.所以 32 位跨越从 -2^31 到 2^31-1 的范围。 Zero is in the non-negative half of the sequence, and you have one negative number that can not be properly negated.零在序列的非负一半中,并且您有一个无法正确取反的负数。

Java ints are stored in a 32-bit two's compliment form. Java 整数以 32 位二进制补码形式存储。 Similar results applies for all two's compliment representations.类似的结果适用于所有二进制表示。 The anomalous behavior is due to the extra negative integer which is an artifat of two's compliment.异常行为是由于额外的负数 integer 造成的,这是两个人的恭维的产物。

-2147483748 has a leadbitwise representation of -2147483748具有前导位表示

10000000 00000000 00000000 00000000

and the negative of a number is achieved by flipping all the bits and adding one to it.一个数的负数是通过翻转所有位并向其加一来实现的。 The largest positive int will have a bitwise representation of最大的正整数将有一个按位表示

01111111 11111111 11111111 11111111

which is 2147483647 .这是2147483647 We then add one more, so bitwise, we have然后我们再添加一个,所以按位,我们有

10000000 00000000 00000000 00000000 == -2147483648

This extra integer is an artifact of the two's compliment representation and operations with this number can have undesirable consequences.这个额外的 integer 是两个补码表示的产物,使用这个数字进行操作可能会产生不良后果。 -2147483748 is indeed unique among the ints! -2147483748在int中确实是独一无二的!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM