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

硬币计数功能实现求助:C#代码无法正确统计硬币总数

问题分析与解决方案

原代码存在的核心问题

  • 循环逻辑完全无效:for (int i =0; i < amount; i++)的循环条件和硬币计算毫无关联,且循环内从未修改amount的值,导致每次判断都用原始金额,永远只会触发第一个满足的条件(比如1.41始终>=0.25,只会计算quarter的数量)。
  • 计算逻辑错误:每个分支直接覆盖answer的值,没有累加不同硬币的数量,也没有扣除已使用的金额,自然无法得到总硬币数。
  • 精度隐患:直接用double处理货币会有精度误差(比如0.1在二进制中是无限循环小数),可能导致计算结果偏差。
  • penny分支逻辑混乱:answer = amount - 0.01完全不符合硬币数量计算的逻辑,无法正确统计penny的数量。

正确解决方案

核心思路是从大面额到小面额依次计算可使用的硬币数量,累加总数,同时扣除已使用的金额。为了避免double的精度问题,建议将金额转换为以分为单位的整数处理,这是处理货币计算的标准做法。

推荐实现(整数精度版)

public static int CalculateCoinCount(double amount)
{
    // 将金额转换为分,用Math.Round确保四舍五入到两位小数,避免double精度误差
    int totalCents = (int)Math.Round(amount * 100);
    int coinCount = 0;

    // 定义硬币面额(单位:分),按从大到小排序
    int[] coinDenominations = { 25, 10, 5, 1 };

    foreach (int denomination in coinDenominations)
    {
        // 计算当前面额可使用的硬币数量
        int count = totalCents / denomination;
        coinCount += count;
        // 扣除已使用的金额
        totalCents -= count * denomination;
    }

    return coinCount;
}

代码说明

  • 转换为整数后彻底避免了double的精度问题,比如1.41会被正确转换为141分。
  • 遍历每个面额时,先算能使用的最大数量,累加后扣除对应金额,再处理下一个小面额。
  • 以1.41为例:141分 → 5个quarter(125分)→ 剩余16分 → 1个dime(10分)→ 剩余6分 →1个nickle(5分)→剩余1分→1个penny,总数5+1+1+1=8,完全符合预期。

兼容double的实现(不推荐,仅作参考)

如果必须直接使用double处理,需要注意精度修正,同时正确更新剩余金额:

public static int CalculateCoinCount(double amount)
{
    int coinCount = 0;
    // 初始化剩余金额,用Math.Round确保两位小数精度
    double remaining = Math.Round(amount, 2);

    // 处理quarter(0.25)
    int quarterCount = (int)(remaining / 0.25);
    coinCount += quarterCount;
    remaining -= quarterCount * 0.25;
    remaining = Math.Round(remaining, 2); // 修正精度误差

    // 处理dime(0.10)
    int dimeCount = (int)(remaining / 0.10);
    coinCount += dimeCount;
    remaining -= dimeCount * 0.10;
    remaining = Math.Round(remaining, 2);

    // 处理nickle(0.05)
    int nickleCount = (int)(remaining / 0.05);
    coinCount += nickleCount;
    remaining -= nickleCount * 0.05;
    remaining = Math.Round(remaining, 2);

    // 处理penny(0.01)
    int pennyCount = (int)Math.Round(remaining / 0.01);
    coinCount += pennyCount;

    return coinCount;
}

关于while循环崩溃的原因

你改用while循环后崩溃,大概率是因为没有正确更新循环终止条件:比如剩余金额没有被正确扣除,导致循环无限执行(比如remaining始终大于0,却没有减少,进入死循环)。只要按照上面的逻辑,每次处理完一个面额后更新剩余金额,while循环也能正常工作,比如:

public static int CalculateCoinCount(double amount)
{
    int totalCents = (int)Math.Round(amount * 100);
    int coinCount = 0;
    int[] denominations = {25,10,5,1};
    int index = 0;

    while (totalCents > 0 && index < denominations.Length)
    {
        int denom = denominations[index];
        if (totalCents >= denom)
        {
            coinCount++;
            totalCents -= denom;
        }
        else
        {
            index++;
        }
    }
    return coinCount;
}

内容的提问来源于stack exchange,提问作者Miguel Freytes-Calderon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 06:25:34