Lab 04: Unit Converter
Integer division, modulus, type casting, and formatted output
After this lab, you will be able to:
- Use integer division (
/) and modulus (%) to decompose values into larger units - Cast between
intanddoubleto control division behavior - Format output with
System.out.printfand format specifiers - Distinguish when integer division is useful vs. when it causes bugs
What You’re Building
You will write a unit converter that takes a total number of minutes and breaks it into hours and minutes, computes a percentage, and formats everything with printf. This lab drills the difference between integer division (which truncates) and floating-point division (which preserves decimals) — a distinction that does not exist in Python 3.
Concepts and Misconceptions
| Concept | Common Mistake | What the Test Catches |
|---|---|---|
| Integer division | Expecting 7 / 2 to produce 3.5 (it produces 3) |
Incorrect hours or minutes value |
| Modulus | Confusing % with percentage; writing minutes % 100 instead of minutes % 60 |
Remainder exceeds 59 |
| Casting | Casting the result instead of the operand: (double)(a / b) vs (double) a / b |
Percentage is 0.0 instead of correct value |
printf format |
Missing %n or \n at end of format string |
Output lines merge together |
Checkpoints
Checkpoint 1: Convert Minutes to Hours and Minutes
What to do: Given int totalMinutes, compute hours = totalMinutes / 60 and remaining = totalMinutes % 60. Print in the format: "3 hours and 27 minutes".
What the test checks: For input 207, output is exactly "3 hours and 27 minutes".
Debugging tip: If hours is correct but minutes is wrong, double-check your modulus divisor. % 60 gives minutes remaining after full hours. % 100 is a common mistake that gives a meaningless value.
Checkpoint 2: Compute a Percentage with Casting
What to do: Compute what percentage of a full day (1440 minutes) the input represents. Cast to double before dividing: (double) totalMinutes / 1440 * 100.
What the test checks: The percentage is a double with the correct value (e.g., 14.375 for 207 minutes). Integer division would produce 0.0.
Debugging tip: If your result is 0.0, check where the cast is. (double)(207 / 1440) casts after integer division — the damage is already done. The cast must go on one of the operands before the / operator.
Checkpoint 3: Format Output with printf
What to do: Rewrite your output using System.out.printf. Display hours and minutes as integers and the percentage to two decimal places: printf("%d hours, %d minutes (%.2f%%)%n", hours, remaining, pct).
What the test checks: Output matches the exact format, including two decimal places and the % sign.
Debugging tip: To print a literal % with printf, use %%. A single % is a format specifier prefix, so printf("85%") will crash with java.util.MissingFormatArgumentException. Write printf("85%%") instead.
How to Debug
-
Test with edge cases. Try
totalMinutes = 0,60,61, and1440. Zero and exact multiples of 60 reveal off-by-one errors.1440should produce100.00%. -
Print the raw division. Before formatting, print
totalMinutes / 1440and(double) totalMinutes / 1440on separate lines. If both produce the same integer result, your cast is missing or misplaced. -
Check
printfargument count.printfcrashes at runtime (not compile time) if the number of%specifiers does not match the number of arguments. Count them: each%d,%f, or%sneeds exactly one corresponding argument, in order.
Scoring
| Component | Points | Criteria |
|---|---|---|
| Checkpoints | 3 | 1 pt each. Binary: the checkpoint test passes or it does not. |
| Autograder | 5 | Correctness across all test cases. Partial credit by proportion of tests passed. |
| Timeliness | 2 | Full credit if submitted by the due date. 0 if late. |
| Total | 10 |