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

C语言浮点数精度问题:找零程序计算出错如何锁定小数位

根因说明

你遇到的问题确实由浮点数精度问题导致:

  • 0.1、0.05、0.01这类十进制小数无法通过二进制浮点数精确存储,实际存储值会和理论值存在微小误差,比如0.1可能存储为0.099999994,做减法比较时就会出现预期外的结果。
  • 你代码中还有两个额外bug加重了异常:1. 硬币面值数组里的镍币面值写错为0.5,正确应为0.05;2. 没有对数组下标i做边界判断,当剩余金额小于1分时i会持续递增,越界访问内存导致输出乱码、程序卡死。
最优修复方案

核心思路是将所有金额转换为以分为单位的整数运算,完全规避浮点数精度问题,修改点如下:

  1. 输入金额后直接转换为整数分,加微小偏移量解决浮点数转整数的截断误差
  2. 所有硬币面值统一改为以分为单位的整数值
  3. 增加数组下标边界判断,避免越界访问
  4. 完善负数输入的校验逻辑,支持用户重新输入

修改后完整代码:

#include <stdio.h>
#include <cs50.h>

int main (void)
{
    // 完善输入校验,要求用户必须输入正数
    float number;
    do
    {
        number = get_float("Number: ");
        if (number < 0)
        {
            printf("A positive number, Please: \n");
        }
    } while (number < 0);
   
    // 转成以分为单位的整数,加1e-6避免浮点数截断误差
    int total_cents = (int)(number * 100 + 1e-6);

    // 硬币面值统一为分单位整数
    int coinValues[] = {100, 25, 10, 5, 1};
    char *coinNames[] = {"Dollar(s): ", "Quarter(s): ", "Dime(s): ", "Nickel(s): ", "Penny(ies): "};
    int i = 0;
    int tmp = 0;
    int coin_count = sizeof(coinValues) / sizeof(coinValues[0]); // 硬币种类总数,用于边界判断

    while (total_cents > 0 && i < coin_count)
    {
        if (total_cents >= coinValues[i])
        {
            printf("%s", coinNames[i]);
            tmp = 0;
            while (total_cents >= coinValues[i])
            {
                total_cents -= coinValues[i];
                tmp++;
            }
            printf("%i\n", tmp);
        }
        else
        {
            i++;
        }
    }
    
    return 0;
}
验证效果

输入2.6时,转换为整数是260分,计算逻辑为:

  • 260 / 100 = 2个Dollar,剩余60分
  • 60 / 25 = 2个Quarter,剩余10分
  • 10 / 10 = 1个Dime,剩余0分直接结束循环,完全符合预期。

内容的提问来源于stack exchange,提问作者Will Felipe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 02:24:04