Java现金找零代码异常:0.41倍数金额计算错误求助
问题根源:浮点数精度误差
你遇到的问题是典型的浮点数精度丢失导致的。double类型基于二进制存储,无法精确表示所有十进制小数(比如0.41),这类小数在二进制中是无限循环的近似值。当你反复对amount做减法时,误差会累积,最终导致最后一步判断amount >= 0.01时,实际的amount是一个略小于0.01的数值(例如0.00999999999999995),循环不会执行,因此少算了1便士。
解决方案:用整数处理货币金额
处理货币时,最佳实践是用整数表示分,而非浮点数表示美元。所有运算都用整数执行,彻底避免精度问题。
修改后的代码如下:
import java.util.Scanner; public class Cash { public static void main(String[] args){ Scanner scanner_obj = new Scanner(System.in); System.out.print("Enter Amount: $"); // 将输入的美元金额转换为分(用Math.round避免转换误差) int cents = (int) Math.round(Double.parseDouble(scanner_obj.nextLine()) * 100); int[] change = calc_Change(cents); System.out.println(change[0] + " Quarters"); System.out.println(change[1] + " Dimes"); System.out.println(change[2] + " Nickels"); System.out.println(change[3] + " Pennies"); System.out.println(check_Change(cents, change)); } public static int[] calc_Change(int cents){ int[] change = {0, 0, 0, 0}; // 所有面值用分表示 while (cents >= 25){cents -= 25; change[0] += 1;} while (cents >= 10){cents -= 10; change[1] += 1;} while (cents >= 5){cents -= 5; change[2] += 1;} while (cents >= 1){cents -= 1; change[3] += 1;} return change; } public static boolean check_Change(int cents, int[] change){ int total = change[0]*25 + change[1]*10 + change[2]*5 + change[3]*1; System.out.println(cents + " cents vs " + total + " cents"); return (cents == total); } }
关键改动说明
- 输入转换:将美元金额乘以100后用
Math.round取整,得到精确的分数值,避免直接转换时的精度误差 - 整数运算:所有硬币面值和计算都用整数(分)执行,完全消除浮点数精度问题
- 验证逻辑:同样改用整数计算总金额,确保对比的准确性
测试0.41美元时,转换为41分,计算后会得到1 Quarters、1 Dimes、1 Nickels、1 Pennies,总和41分,完全符合预期。
内容的提问来源于stack exchange,提问作者Artyom Yesayan
相关产品推荐
相关产品推荐

