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