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

CS50 Pset1 Cash贪心算法问题:4.2美元找零计算错误求助

解决CS50找零硬币程序的精度问题

嘿,我一眼就看出你碰到了编程里一个经典的浮点数精度陷阱!这也是很多人刚开始处理货币计算时会踩的坑。

问题根源

你输入4.2美元时,程序输出22而非正确的18,核心原因是float类型无法精确表示所有十进制小数。比如4.2这个数,在二进制浮点数里是一个无限循环的近似值,当你执行change_owed * 100时,得到的并不是精确的420,而是一个非常接近420的数(比如419.999969)。你的循环会把这个值当成比420小一点的数来处理,导致最后多算了好几枚1美分硬币。

另外,你的代码里还有一个小bug:do-while循环的条件里用了未定义的变量c,应该改成判断change_owed < 0才行。

修复方案

解决这个问题的关键是避免用浮点数处理货币单位,转用整数来存储美分。具体可以用round()函数把浮点数转换后的近似值四舍五入到最近的整数,确保得到准确的美分数。

修改后的代码如下:

#include<stdio.h>
#include<cs50.h>
#include<math.h> // 必须包含math.h才能使用round函数

int main(void) {
    float change_owed;
    int change_owed_in_cents; // 用整数存储美分,彻底避免精度问题
    int number_of_coins_to_be_given = 0;
    
    do {
        printf("Enter the positive amount of change owed in dollars: ");
        change_owed = get_float();
    } while(change_owed < 0); // 修复未定义变量c的问题
    
    // 用round函数修正浮点数精度误差,再转为整数
    change_owed_in_cents = round(change_owed * 100);
    
    while(change_owed_in_cents >= 25){
        change_owed_in_cents -= 25;
        number_of_coins_to_be_given++;
    }
    while(change_owed_in_cents >= 10) {
        change_owed_in_cents -= 10;
        number_of_coins_to_be_given++;
    }
    while(change_owed_in_cents >= 5) {
        change_owed_in_cents -= 5;
        number_of_coins_to_be_given++;
    }
    while(change_owed_in_cents >= 1) {
        change_owed_in_cents -= 1;
        number_of_coins_to_be_given++;
    }
    printf("%d\n", number_of_coins_to_be_given);
}

为什么这样改有效

  • round()函数会把4.2*100得到的近似值(比如419.999969)四舍五入为准确的420,确保后续计算基于正确的美分数。
  • 使用整数类型存储美分,后续的减法和比较运算都不会再有精度损失。
  • 修复了do-while循环的条件错误,确保只有正数输入才会被接受。

现在再测试4.2美元的情况,程序会正确计算出18枚硬币:16枚25美分+2枚10美分,完美符合最少硬币的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 03:55:56