i的值(i == -i&& i!= 0)在Java中返回true

时间:2013-07-22 06:24:28

标签: java

我有以下if条件。

if (i == -i && i != 0)

i在Java中对此条件返回true的值是什么?

在Java中考虑two's complement符号时,我无法想到i的任何此类值。

我还希望得到这种情况的任何答案的代数证明(在Java的上下文中)?

6 个答案:

答案 0 :(得分:125)

唯一适用的int值为Integer.MIN_VALUE

这是因为整数被two's complement way否定了。

使用

System.out.println(Integer.toBinaryString(Integer.MIN_VALUE));

您看到Integer.MIN_VALUE

10000000000000000000000000000000

通过首先交换01来获取负值,这会给出

01111111111111111111111111111111

并添加1,其中包含

10000000000000000000000000000000

正如您在我给出的链接中所看到的,维基百科提到了最负数的问题,并指出它是唯一的例外:

  

两个补码中最负的数字有时被称为“   奇怪的数字,“因为这是唯一的例外。

如果您将Long.Min_Value存储在long变量中,则0会出现相同的现象。

请注意,这仅仅是由于对Java中的int二进制存储的选择。另一个(坏的)解决方案可能是通过简单地改变最高有效位并让其他位保持不变来否定,这可以避免MIN_VALUE的这个问题但是会产生2个不同的{{1}}值和复杂的二进制算术(例如,你会如何增加?)。

答案 1 :(得分:25)

您要查找的值是Integer.MIN_VALUE


  

我还希望能得到这种情况的任何答案的代数证明(在java的上下文中)?

这是Stack Exchange的主题。但是你可以从Java整数(JLS 4.2

的定义开始
  

“整数类型是byte,short,int和long,其值为8位,16位,32位和64位带符号的二进制补码整数......”

  

“整数类型的值是以下范围内的整数......       对于int,从-2147483648到2147483647,包含“

和Java一元' - '运算符(JLS 15.15.4)的定义:

  

“对于整数值,否定与从零减法相同.Java编程语言对整数使用二进制补码表示,并且二进制补码值的范围不对称,因此否定最大负值int或long导致相同的最大负数。在这种情况下会发生溢出,但不会抛出异常。对于所有整数值x,-x等于(~x)+1。“

答案 2 :(得分:18)

除了目前给出的答案之外......

总共有四个值

int i = Integer.MIN_VALUE;
long i = Long.MIN_VALUE;
Integer i = Integer.valueOf(Integer.MIN_VALUE);
Long i = Long.valueOf(Long.MIN_VALUE);

包装的值将被解包,因此对于此表达式它们也是如此。

注意:Math.abs文档。

  

public static int abs(int a)

     

返回int的绝对值   值。如果参数不是负数,则返回参数。如果   如果论证是否定的,则会返回对论证的否定。

     

请注意,如果参数等于Integer.MIN_VALUE的值,   最负面可表示的int值,结果是一样的   价值,这是负面的。

  

public static long abs(long a)

     

返回long值的绝对值。如果论证不是   否定,返回参数。如果论证是否定的,那么   否定了论证。

     

注意,如果参数等于Long.MIN_VALUE的值,则   最负面可表示的长值,结果是相同的值,   这是消极的。

令人惊讶的是Math.abs可能会返回一个负数。发生这种情况要么是因为a)在这些情况下-MIN_VALUE没有正值b)执行-计算导致溢出。

还有什么兴趣是为什么没有Byte.MIN_VALUE,Short.MIN_VALUE不这样做。这是因为-将类型更改为int,因此没有溢出。

Character.MIN_VALUE没有问题,因为它是0。

Float.MIN_VALUE和Double.MIN_VALUE具有不同的含义。这些是大于零的最小可表示值。因此,它们具有有效的负值,而不是它们本身。

答案 3 :(得分:14)

与其他人提到的一样,这只能由Integer.MIN_VALUE来实现。至于证明,让我提供一个比二进制更容易理解的解释(虽然它仍然根植于此)。

请注意,Integer.MIN_VALUE等于-2^31-2147483648Integer.MAX_VALUE等于2^31-12147483647-Integer.MIN_VALUE2^31,现在对于整数来说太大了(因为它已超过MAX_VALUE),从而导致整数溢出,再次使其成为Integer.MIN_VALUE。它是唯一执行此操作的Integer,因为MIN_VALUE是除0之外没有负等价的唯一数字。

答案 4 :(得分:6)

使用modulo 2^32算术的暂定代数证明:

i == -i可以重写为2 * i == 0(双方都添加i)或i << 1 == 0

此等式有i == 0 >> 1形式的两个解,即0b10000000000000000000000000000000b,通过左移01获得。< / p>

排除解决方案i == 0,仍有解决方案i == 100000000000000000000000000000000b

答案 5 :(得分:0)

也许它不是太教育,但不是认为你可以运行这段代码:

    for (int i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++)
    {
        if (i == -i && i != 0)
        {
            System.out.println(i);
        }
    }

看到它打印

-2147483648
-2147483648

无限地:)