Java Reference
In-Depth Information
< Day Day Up >
Puzzle 35: Minute by Minute
The following program simulates a simple clock. Its loop variable represents a millisecond counter
that goes from 0 to the number of milliseconds in an hour. The body of the loop increments a
minute counter at regular intervals. Finally, the program prints the minute counter. What does it
print?
public class Clock {
public static void main(String[] args) {
int minutes = 0;
for (int ms = 0; ms < 60*60*1000; ms++)
if (ms % 60*1000 == 0)
minutes++;
System.out.println(minutes);
}
}
Solution 35: Minute by Minute
The loop in this program is the standard idiomatic for loop. It steps the millisecond counter ( ms )
from 0 to the number of milliseconds in an hour, or 3,600,000, including the former but not the
latter. The body of the loop appears to increment the minute counter ( minutes ) each time the
millisecond counter is a multiple of 60,000, which is the number of milliseconds in a minute. This
happens 3,600,000 / 60,000, or 60 times in the lifetime of the loop, so you might expect the
program to print 60 , which is, after all, the number of minutes in an hour. Running the program,
however, tells a different story: It prints 60000 . Why does it increment minutes so often?
The problem lies in the boolean expression (ms % 60*1000 == 0) . You might think that this
expression is equivalent to (ms % 60000 == 0) , but it isn't. The remainder and multiplication
operators have the same precedence [JLS 15.17], so the expression ms % 60*1000 is equivalent to
(ms % 60) * 1000 . This expression is equal to 0 if (ms % 60) is 0, so the loop increments minutes
every 60 iterations. This accounts for the final result being off by a factor of a thousand.
The easiest way to fix the program is to insert a pair of parentheses into the boolean expression to
 
 
Search WWH ::




Custom Search