Java找零程序Bug求助:2.03等测试用例金额计算异常
Hey there! The bug you're hitting with test cases like 2.03 is a super common gotcha when using double for currency values—let's break down why this happens and how to fix it.
Why Your Current Code Fails
Floating-point types like double can't represent decimal values exactly in binary. Numbers like 0.01 (a penny) are infinite repeating fractions in binary, which leads to tiny precision errors that accumulate as you run calculations.
Take your 2.03 example:
- You calculate
2.03 / 0.25 = 8.12, then truncate to get 8 quarters. - Subtracting
8 * 0.25 = 2.0from2.03should leave0.03, but due to floating-point imprecision, the actual stored value is something like0.029999999999999805. - Dividing this by
0.10gives0.29999999999999805—truncating to 0 dimes. - The same issue hits nickels, leaving that tiny leftover value. Dividing by
0.01gives2.9999999999999805, which truncates to 2 pennies instead of the correct 3.
The Solution: Use Integer Arithmetic for Currency
The best way to avoid these precision errors is to convert your amount into cents (an integer) right at the start. Integers can be represented exactly, so all your calculations will be precise.
Here's the revised code:
import java.util.Scanner; public class Exercise9 { public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.print("Amount : "); double amountInput = input.nextDouble(); // Convert to cents, using Math.round to fix initial precision drift int totalCents = (int) Math.round(amountInput * 100); // Calculate each coin type with integer division int quarters = totalCents / 25; totalCents -= quarters * 25; int dimes = totalCents / 10; totalCents -= dimes * 10; int nickels = totalCents / 5; totalCents -= nickels * 5; int pennies = totalCents; // Output results System.out.println("\nQuarters : " + quarters); System.out.println("Dimes : " + dimes); System.out.println("Nickels : " + nickels); System.out.println("Pennies : " + pennies); System.out.println("Remaining cents : " + totalCents); } }
Key Changes Explained
- Convert to Cents: Multiplying by 100 and rounding fixes initial precision issues (e.g.,
2.03 * 100might otherwise become202.99999999999997, butMath.roundcorrects it to203). - Integer Division: Using
intfor all calculations means we skip floating-point truncation—division naturally gives the whole number of coins we can use. - Simplified Logic: No more subtracting
(quarters % 1)to get the integer count; integer division does that work directly.
This code will handle 2.03 correctly: it outputs 8 quarters, 0 dimes, 0 nickels, and 3 pennies—exactly what you expect.
内容的提问来源于stack exchange,提问作者John

