简体   繁体   English

为什么Integer.MIN_VALUE的绝对值等于Integer.MIN_VALUE

[英]Why is absolute of Integer.MIN_VALUE equivalent to Integer.MIN_VALUE

In java when I say Integer i = Math.abs(Integer.MIN_VALUE) . 在java中我说Integer i = Math.abs(Integer.MIN_VALUE) I get the same value as the answer,which means i contains Integer.MIN_VALUE . 我得到与答案相同的值,这意味着i包含Integer.MIN_VALUE I have verified the same in C++ as well. 我在C ++中也验证了相同的内容。

Why this behavior? 为什么会这样?

Read this in Effective Java by Joshua Bloch. 请阅读Joshua Bloch的Effective Java中的内容。

I found the answer for this question and here is the explanation: Computers work with binary arithmentic, the logic of Math.abs in java or the absolute function in any language is like below: 我找到了这个问题的答案,这里是解释:计算机使用二进制算术,java中Math.abs的逻辑或任何语言的absolute函数如下所示:

if(num >= 0)
    return num;
else
    return (2's complement of the num);

Note : How to find 2's complement 注意:如何找到2的补码

For a given number, we find it's 1's complement first and then add 1 to it. 对于给定的数字,我们首先发现它是1的补码,然后加1。 For eg Consider our number to be 10101 1's complement= 01010 2's complement= 01011 (added 1 to the 1`s complement) 例如,考虑我们的数字是10101 1的补数= 01010 2的补数= 01011 (1补充加1)

Now, for the sake of making it easy and clear, let us say that our Integer(signed) size is 3 bit, then here is the possible list of numbers which can be produced using the four bits: 现在,为了使其简单明了,我们假设我们的整数(带符号)大小是3位,那么这里是可以使用四位产生的数字列表:

000 --> 0 (0)
001 --> 1 (1)
010 --> 2 (2)
011 --> 3 (3) 
100 --> 4 (-4)
101 --> 5 (-3)
110 --> 6 (-2)
111 --> 7 (-1)

Now that this is signed, it means half of the numbers are negative and the other half are positive(The negative numbers are the ones with the first bit 1). 现在这已经签名,这意味着一半的数字是负数而另一半是正数(负数是第一位1的数字)。 Let us start from 000 and try to find its negative number, it would be the two's complement of 000 . 让我们从000开始并试图找到它的负数,它将是000的两个补码。

2's complement of `000` = 1 + `111` = `000`
2's complement of `001` = 1 + `110` = `111`
2's complement of `010` = 1 + `101` = `110`
2's complement of `011` = 1 + `100` = `101`
2's complement of `100` = 1 + `011` = `100`
2's complement of `101` = 1 + `010` = `011`
2's complement of `110` = 1 + `001` = `010`  
2's complement of `111` = 1 + `000` = `001`

From the above demonstration, we find that 2's complement of 111(-1) is 001(1) , similarly 2's complement of 110(-2) is 010(2) , 2's complement of 101(-3) is 011(3) and 2's complement of 100(-4) is 100(-4) and as we can see that -4 is the smallest negative number possible using 3 bits. 从上面的演示中,我们发现111(-1) is 001(1) 2的补码111(-1) is 001(1) ,类似的110(-2) is 010(2) 2的补码110(-2) is 010(2)101(-3) is 011(3) 2的补数101(-3) is 011(3)并且2的100(-4) is 100(-4)的补码100(-4) is 100(-4) ,并且我们可以看出-4是使用3位可能的最小负数。

This is the reason why absolute of Integer.MIN_VALUE is Integer.MIN_VALUE . 这就是为什么绝对的理由Integer.MIN_VALUEInteger.MIN_VALUE

There is an inherent asymmetry that is the root cause of this effect. 存在固有的不对称性是这种效应的根本原因。 The number of 32-bit bit patterns is even. 32位位模式的数量是偶数。 One of those patterns is used for zero. 其中一种模式用于零。 That leaves an odd number of non-zero values. 这留下了奇数个非零值。 The number of positive values and the number of negative values cannot be equal because their sum is odd. 正值的数量和负值的数量不能相等,因为它们的总和是奇数。

In the 2's complement representation used for Java integers, the number of negative numbers is one greater than the number of positive numbers. 在用于Java整数的2的补码表示中,负数的数量比正数的数量大1。 Each negative number other than Integer.MIN_VALUE corresponds to a positive number that is both its negation and its absolute value. 除Integer.MIN_VALUE之外的每个负数对应于正数,该正数既是其否定值,也是其绝对值。 Integer.MIN_VALUE is left over, with no corresponding positive int. Integer.MIN_VALUE保留,没有相应的正int。 Math.abs and negation map it to itself. Math.abs和否定将它映射到自身。

Why this behavior? 为什么会这样?

It is a mathematical consequence of the choice of representation used in all modern computers. 它是所有现代计算机中使用的表示选择的数学结果。

Here's an informal proof of why it has to be that way. 这就是为什么是这样一个非正式的证据。

  1. A signed binary number representation with N bits has 2 N possible values; 具有N位的带符号二进制数表示具有2 N个可能值; ie a set integers with an even number of elements. 即具有偶数个元素的集合整数。

  2. Remove zero from the set. 从集合中删除零。 The set is now has an odd number of elements. 该集合现在具有奇数个元素。

  3. Now remove all pairs of numbers of the form {n, -n} . 现在,删除所有形式的数字{n, -n} Each time we remove a pair of numbers, the set still contains an odd number of elements. 每次我们删除一对数字时,该集合仍然包含奇数个元素。

  4. We are now left with a set that contains an odd number of integers for which n is in the set, but -n is not in the set. 我们现在留下一个包含奇数个整数的集合,其中n在集合中,但-n不在集合中。 Since the set size is odd, it cannot be empty; 由于设定的大小是奇数,因此不能为空; ie there is at least one number with this property. 至少有一个具有此属性的数字。

In the representations specified by Java (and indeed used all other practical languages), integer types have 2 N-1 negative values and 2 N-1 - 1 values greater than zero. 在Java指定的表示中(实际上使用了所有其他实用语言),整数类型具有2个N-1个负值和2 大于零的N-1 - 1个值。 The value that has the strange property is MIN_VALUE . 具有奇怪属性的值是MIN_VALUE This representation is called two's complement . 这种表示称为二进制补码


Strictly speaking, an integer representation doesn't have to have this anomaly: 严格来说,整数表示不必具有此异常:

  • It is possible to have two zeros (-0 and +0); 可以有两个零(-0和+0); eg signed magnitude or one's complement representations. 例如有符号幅度一个补码表示。 (This invalidates step 2 of the proof: there are now 2 zeros to remove.) (这使证明的第2步无效:现在有2个零要删除。)

  • It is possible to exclude -2 N-1 ; 可以排除-2 N-1 ; ie make it an illegal value. 即使它成为非法的价值。 (This invalidates step 1 of the proof: the initial set now has an odd number of values.) (这使证明的第1步无效:初始集现在具有奇数个值。)

  • It is possible to specify integer arithmetic so that (for example) negating MIN_VALUE raises an exception. 可以指定整数运算,以便(例如)否定MIN_VALUE引发异常。 For instance Math.abs(Integer.MIN_VALUE) would throw an exception. 例如, Math.abs(Integer.MIN_VALUE)会抛出异常。

However, all of these things have significant performance implications, especially since modern computer hardware only supports twos-complement arithmetic natively. 然而,所有这些都具有重要的性能影响,特别是因为现代计算机硬件本身仅支持二进制补码算法。 They also have issues in relation to writing reliable integer codes ... 它们在编写可靠的整数代码方面也存在问题......

Math.abs(int) docs says If the argument is negative, the negation of the argument is returned. Math.abs(int)docs说如果参数是负数,则返回参数的否定。 JLS 15.15.4. JLS 15.15.4。 Unary Minus Operator says For all integer values x, -x equals (~x)+1 . 一元减运算符表示对于所有整数值x,-x等于(~x)+1

-Integer.MIN_VALUE = ~Integer.MIN_VALUE + 1 = ~0x80000000 + 1 = 0x7FFFFFFF + 1 = 0x80000000 = Integer.MIN_VALUE -Integer.MIN_VALUE = ~Integer.MIN_VALUE + 1 = ~0x80000000 + 1 = 0x7FFFFFFF + 1 = 0x80000000 = Integer.MIN_VALUE

You might expect that absolute value of Integer.MIN_VALUE would be Integer.MAX_VALUE + 1 , but this value is out of primitive int size. 您可能期望Integer.MIN_VALUE绝对值为Integer.MAX_VALUE + 1 ,但此值超出原始int大小。 And Integer.MAX_VALUE + 1 is Integer.MIN_VALUE again. 并且Integer.MAX_VALUE + 1再次为Integer.MIN_VALUE That's all. 就这样。

This is because of the way two's-complement number systems work. 这是因为二进制数系统的工作方式。 Integer.MIN_VALUE corresponds to 0x80000000. Integer.MIN_VALUE对应于0x80000000。 The standard way to negate it is to take its ones' complement (0x7FFFFFFF in this case) and add 1, and in this case it would overflow back to 0x80000000. 否定它的标准方法是取其补码(在这种情况下为0x7FFFFFFF)并加1,在这种情况下它将溢出回0x80000000。

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

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