Josh: Hi. We're Click and Hack, the type-it brothers. Welcome to Code Talk. Today we're going to talk about loops.
Neal: What, Froot Loops?
Josh: No you dingbat, while loops! What does this loop do?
while (i == i + 1) ;
Neal: It's obvious: that loop does nothing. A number is never equal to itself plus one.
Josh: Well, maybe yes, maybe no... What if it's preceded by this declaration?
double i = 1.0 / 0.0;
Believe it or not, this is legal. The Java™ programming language uses IEEE 754 arithmetic, which lets you store infinity in a double (or float). And as we learned in grade school, infinity plus one is still infinity, so the loop condition evaluates to true and the loop never terminates!
In fact, you don't even need to store infinity in i to make the loop spin forever; any sufficiently large value will do, for example:
double i = 1.0e40;
Neal: Oh I see, the larger a floating point number, the larger the distance between the number and its successor. Adding one to a floating point number this large doesn't "bridge the gap" to its successor.
Josh: Yep. Here's another one. What does this loop do?
while (i != i) ;
Neal: It has to do nothing, right?
Josh: Well, no... Suppose it's preceded by this declaration:
double i = 0.0 / 0.0;
This strange looking expression evaluates to Double.NaN, which is short for "not a number." It turns out that, according to the IEEE 754 spec, NaN is not equal to itself! Strange but true. Once again, the expression evaluates to true, and the loop spins forever.
Neal: So what can we learn from all of this?
Josh: Three things:
Floating point arithmetic is tricky. Floating point numbers aren't the same as the real numbers that you learned about in school. Be very careful when you're working with floating point, and never use it when integer arithmetic will do.
Give your variables good names. I tried to mislead you by calling the variable i, which suggests that it's an integer.
Last but not least, stop by this site in upcoming weeks for additional installments in this series. We'll entertain you and enlighten you with lots more fun programming puzzlers.
Neal: In the mean time, I have two more puzzlers to keep you busy. Here are two while loops, each of which appears to do nothing but can be made to loop infinitely by preceding it with the correct declaration. Can you figure out what declaration makes each loop spin forever? Both of these puzzlers can (and should) be solved without resorting to floating point.
while (i != i + 0) ;
while (i != 0) i >>>= 1;
Josh: In case you don't have your Java Language Specification handy, >>>= is the assignment operator corresponding to unsigned right shift. Come back next week for the answers. Our thanks go to Ron Gabor, a reader from Herzliya, Israel, for sending us these fine puzzlers. If you want to see your name in print too, send your puzzlers to firstname.lastname@example.org.
Neal: But don't expect us to give any hints!
Josh: And don't code like my brother.
Neal: Don't code like my brother.