Value of i for (i == -i && i != 0) to return true in Java

Java

Java Problem Overview


I have the following if condition.

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

What value of i will return true for this condition in Java?

I am unable to think of any such value of i considering two's complement notation in Java.

I would also love to have algebraic proof of whatever answer this condition has (in context with Java)?

Java Solutions


Solution 1 - Java

The only int value for which it works is Integer.MIN_VALUE.

It's because integers are negated using the two's complement way.

Using

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

you see that Integer.MIN_VALUE is

10000000000000000000000000000000

Taking the negative value is done by first swapping 0 and 1, which gives

01111111111111111111111111111111

and by adding 1, which gives

10000000000000000000000000000000

As you can see in the link I gave, Wikipedia mentions the problem with the most negative numbers and specifies it's the sole exception :

> The most negative number in two's complement is sometimes called "the > weird number," because it is the only exception.

Of course you have the same phenomenon for Long.Min_Value if you store it in a long variable.

Note that this is only due to choices that were made regarding the binary storage of ints in Java. Another (bad) solution could for example have been to negate by simply changing the most significant bit and letting the other bits unchanged, this would have avoided this problem with MIN_VALUE but would have made 2 different 0 values and complicated binary arithmetic (how would you have incremented for example ?).

Solution 2 - Java

The value you are looking for is Integer.MIN_VALUE.


> I would also love to have algebraic proof of whatever answer this condition has(in context with java)?

That's off-topic for Stack Exchange. But you could do it starting from the definition of Java integers (JLS 4.2)

> "The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers ..."

and

> "The values of the integral types are integers in the following ranges ... For int, from -2147483648 to 2147483647, inclusive"

and the definition of the Java unary '-' operator (JLS 15.15.4):

> "For integer values, negation is the same as subtraction from zero. The Java programming language uses two's-complement representation for integers, and the range of two's-complement values is not symmetric, so negation of the maximum negative int or long results in that same maximum negative number. Overflow occurs in this case, but no exception is thrown. For all integer values x, -x equals (~x)+1."

Solution 3 - Java

In additional to the answers given so far...

There is four values in total

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

The wrapped values get unwrapped so they are also true for this expression.

Note: Math.abs documents.

> public static int abs(int a) > > Returns the absolute value of an int > value. If the argument is not negative, the argument is returned. If > the argument is negative, the negation of the argument is returned. > > Note that if the argument is equal to the value of Integer.MIN_VALUE, > the most negative representable int value, the result is that same > value, which is negative.

and

> public static long abs(long a) > > Returns the absolute value of a long value. If the argument is not > negative, the argument is returned. If the argument is negative, the > negation of the argument is returned. > > Note that if the argument is equal to the value of Long.MIN_VALUE, the > most negative representable long value, the result is that same value, > which is negative.

It is surprising that Math.abs might return a negative number. This happens either because a) there is no positive values for -MIN_VALUE in these cases b) performing the - calculation results in an overflow.

What is also interest is why doesn't Byte.MIN_VALUE, Short.MIN_VALUE do not do this. This is because the - changes the type to int for these and thus no overflow.

Character.MIN_VALUE doesn't have a problem because it is 0.

Float.MIN_VALUE and Double.MIN_VALUE have a different meaning. These are the smallest representable value greater than zero. Thus they have valid negative values which are not themselves.

Solution 4 - Java

Like the others have mentioned, this is only fulfilled by Integer.MIN_VALUE. As for proof, let me offer an easier to understand explanation other than in binary (although it is still rooted in that).

Note that Integer.MIN_VALUE is equal to -2^31 or -2147483648 and Integer.MAX_VALUE is equal to 2^31-1 or 2147483647. -Integer.MIN_VALUE is 2^31, which is now too large for an Integer (since it is past MAX_VALUE) thus causing an Integer overflow, making it Integer.MIN_VALUE again. It's the only Integer that does this since MIN_VALUE is the only number with no negative equivalent aside from 0.

Solution 5 - Java

Tentative algebraic proof, using modulo 2^32 arithmetic:

i == -i can be rewritten as 2 * i == 0 (adding i on both sides), or i << 1 == 0.

This equation has two solutions of the form i == 0 >> 1, namely 0b and 10000000000000000000000000000000b obtained by shifting in either 0 or 1 on the left.

The solution i == 0 being excluded, there remains the solution i == 100000000000000000000000000000000b.

Solution 6 - Java

Maybe it's not too educative, but instead of thinking you could run this code:

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

to see that it prints

-2147483648
-2147483648

infinitely :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSunnyView Question on Stackoverflow
Solution 1 - JavaDenys SéguretView Answer on Stackoverflow
Solution 2 - JavaStephen CView Answer on Stackoverflow
Solution 3 - JavaPeter LawreyView Answer on Stackoverflow
Solution 4 - JavaMark MView Answer on Stackoverflow
Solution 5 - JavaYves DaoustView Answer on Stackoverflow
Solution 6 - JavaKubaView Answer on Stackoverflow