CS50 Pset1 Cash问题求助:输出结果与预期不符(18/22)
解决CS50 Pset1 Cash作业的硬币计数错误问题
嘿,刚入坑C语言+CS50的小伙伴,我太懂你遇到这种“大部分情况正常,偏偏某个测试用例翻车”的崩溃感了!咱们来一步步揪出问题根源,搞定这个bug。
最可能的元凶:浮点数精度误差
你代码里用了float change来存储金额,这几乎就是问题的核心!浮点数(float/double)没办法精确表示所有十进制小数,比如你输入的4.30美元,在计算机里可能会被存成4.2999997这类近似值。当你直接把它转成int美分时:
int cents = change * 100; // 这会变成429而不是430!
美分数少了1,后续计算硬币数量自然就错了——比如原本430美分需要17个25分+1个5分(共18枚),但429美分就会变成17个25分+4个1分(共21枚),如果你的测试用例是其他数值,误差累积后就会出现你看到的22枚结果。
具体修改方向
1. 修复浮点数转整数的精度问题
别直接强制转换,用round()函数把浮点数四舍五入到最近的整数,这样就能得到准确的美分数。记得要包含math.h头文件:
#include <math.h> // 必须加这个才能用round // 替换原来的转换代码 int cents = round(change * 100);
这个函数会把4.2999997*100(也就是429.99997)四舍五入成430,完美解决精度丢失的问题。
2. 检查硬币计数逻辑(辅助验证)
确保你是按从大到小的面值顺序计算硬币:先算25分,再10分、5分,最后1分。这种贪心算法才能保证得到最少硬币数。如果你的代码是先算小面值,那也可能导致硬币数偏多,但结合你说“多数输入正常”,这个概率比精度问题小很多。
修正后的示例代码
给你一个完整的参考片段,你可以对比自己的代码调整:
#include <stdio.h> #include <cs50.h> #include <math.h> int main(void) { float change; // 确保输入的金额非负 do { change = get_float("Change owed: "); } while (change < 0); // 精确转换为美分数 int cents = round(change * 100); int total_coins = 0; // 计算25分硬币数量 total_coins += cents / 25; cents = cents % 25; // 计算10分硬币数量 total_coins += cents / 10; cents = cents % 10; // 计算5分硬币数量 total_coins += cents / 5; cents = cents % 5; // 剩下的都是1分硬币 total_coins += cents; printf("%d\n", total_coins); return 0; }
额外小提醒
以后处理货币、金额这类需要精确计算的场景,尽量用整数来表示最小单位(比如美分、分),避免使用浮点数,从根源上杜绝精度问题。
内容的提问来源于stack exchange,提问作者leh_ros
相关产品推荐
相关产品推荐

