You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 14:41:32