Java Reference
In-Depth Information
< Day Day Up >
Puzzle 33: Looper Meets the Wolfman
Provide a declaration for i that turns this loop into an infinite loop. This one doesn't require the use
of any release 5.0 features:
while (i != 0 && i == -i) {
}
Solution 33: Looper Meets the Wolfman
Yet another puzzling looper. In the boolean expression (i != 0 && i == -i ), the unary minus
operator is applied to i , which implies that its type must be numeric: It is illegal to apply the unary
minus operator to a non-numeric operand. Therefore, we are looking for a nonzero numeric value
that is equal to its own negation. NaN does not satisfy this property, as it is not equal to any value,
so i must represent an actual number. Surely there is no number with this property?
Well, there is no real number with this property, but none of Java's numeric types model the real
numbers perfectly. Floating-point values are represented with a sign bit; a significand, informally
known as the mantissa ; and an exponent. No floating-point value other than 0 is equal to itself with
the sign bit flipped, so the type of i must be integral.
The signed integral types use two's-complement arithmetic : To negate a value, you flip every bit and
add 1 to the result [JLS 15.15.4]. One big advantage of two's-complement arithmetic is that there is
a unique representation for 0. If you negate the int value 0 , you get 0xffffffff + 1 , which is 0 .
There is, however, a corresponding disadvantage. There exist an even number of int values— 2 32 to
be precise— and one of these values is used to represent 0. That leaves an odd number of int values
to represent positive and negative integers, which means that there must be a different number of
positive and negative int values. This in turn implies that there is at least one int value whose
negation cannot be correctly represented as an int value.
In fact, there is exactly one such int value, and it is Integer.MIN_VALUE , or -2 31 . Its hexadecimal
representation is 0x8000000 . The sign bit is 1, and all the other bits are 0. If we negate this value,
we get 0x7fffffff + 1 , which is 0x8000000 , or Integer.MIN_VALUE ! In other words,
Integer.MIN_VALUE is its own negation , as is Long.MIN_VALUE . Negating either of these values
causes an overflow, but Java ignores overflows in integer computations. The results are well
defined, even if they are not always what you want them to be.
This declaration will make the boolean expression (i != 0 && i == -i) evaluate to true ,
causing the loop to spin indefinitely:
 
 
Search WWH ::




Custom Search