Java找零程序仅输出整美元面额找零的问题排查
找零程序故障排查
故障根因
你的代码问题和面额拆分的数学逻辑无关,都是实现细节错误,共3处:
- 单位转换逻辑位置错误
你将美元转美分的代码dollars %= 1; dollars *= 100;写在了1美元面额的判断分支内部。如果找零金额不足1美元(比如你测试的3.25元商品付4元,找零0.75元的场景),(int) dollars / 1 > 0的判断条件不成立,单位转换逻辑根本不会执行。后续美分面额计算拿0.75这个美元单位的数值直接除以25/10/5/1,取整结果全为0,自然不会输出任何硬币找零结果。 - 美分计算漏写取余步骤
你在计算20/10/5美元、25/10美分面额后,都通过取余操作扣减了已计算的金额,但计算5美分(Nickels)后漏写了dollars %= 5;,剩余金额没有扣减5美分部分,会导致最终便士(Pennies)的计算结果偏大,这就是小面额美分计算失效的直接原因。 - 浮点数精度隐患
用double类型存储金额存在二进制浮点数精度缺陷,0.1、0.01这类十进制小数无法被二进制浮点数精确表示,多次运算后会出现类似0.1存储为0.09999999999999987的误差,强转int时会直接截断小数部分,很容易出现少算1美分的问题;同时直接用==判断两个double值是否相等也存在误判风险。
修复方案
所有金额计算统一转成最小货币单位(美分)用整数运算,从根源避免浮点数误差,同时修正逻辑分支位置、补全取余步骤:
import java.util.Scanner; public class CustomerChange { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // 全部以美分为单位用整数存储,彻底规避浮点数精度问题 int costCent; int cashCent; int changeCent; System.out.println("Price: "); // 输入金额转美分,四舍五入修正输入阶段的精度误差 costCent = (int) Math.round(scanner.nextDouble() * 100); System.out.println("Cash: "); cashCent = (int) Math.round(scanner.nextDouble() * 100); if (cashCent < costCent) { System.out.println("Not enough cash. Goodbye."); } else if (cashCent == costCent) { System.out.println("Thank you. Goodbye."); } else { changeCent = cashCent - costCent; System.out.println("\nChange: \n"); // 计算整美元面额(1美元=100美分) int twenties = changeCent / 2000; if (twenties > 0) { System.out.println("Twenties: " + twenties); changeCent %= 2000; } int tens = changeCent / 1000; if (tens > 0) { System.out.println("Tens: " + tens); changeCent %= 1000; } int fives = changeCent / 500; if (fives > 0) { System.out.println("Fives: " + fives); changeCent %= 500; } int ones = changeCent / 100; if (ones > 0) { System.out.println("Ones: " + ones); changeCent %= 100; } // 计算美分面额 int quarters = changeCent / 25; if (quarters > 0) { System.out.println("Quarters: " + quarters); changeCent %= 25; } int dimes = changeCent / 10; if (dimes > 0) { System.out.println("Dimes: " + dimes); changeCent %= 10; } int nickels = changeCent / 5; if (nickels > 0) { System.out.println("Nickels: " + nickels); changeCent %= 5; } int pennies = changeCent; if (pennies > 0) { System.out.println("Pennies: " + pennies); } } scanner.close(); } }
修复后测试你提到的两个场景:
- 输入价格3.25、支付4:找零0.75美元,正确输出3个25美分
- 输入价格168.75、支付200:找零31.25美元,正确输出1张20、1张10、1张1、1个25美分,小面额计算无异常
内容的提问来源于stack exchange,提问作者NaplesAnonymous
相关产品推荐
相关产品推荐

