CS50x Pset1现金找零程序异常:0.41与4.2计算结果错误求助
解决CS50x Pset1现金找零的浮点精度问题
哦,这个坑我见太多了——CS50的现金找零题里,浮点数的精度误差绝对是新手最容易踩的陷阱之一!
问题根源:浮点数的二进制表示缺陷
你遇到的0.41返回3、4.2返回22的问题,本质是十进制小数无法被二进制浮点数精确表示。举个具体的例子:
- 当你输入
0.41时,计算机用float或double存储的实际值可能是0.4099999999999999这类接近但略小于0.41的数 - 如果你直接把这个值乘以100并强制转成整数(比如
int cents = 0.41 * 100;),结果会被截断成40而不是41 - 用40美分计算硬币数量:25+10+5=40,刚好3个,但实际需要4个(25+10+5+1),结果自然错了
同理,4.2会被存成接近4.199999999999999的值,乘以100后变成419,计算出来的硬币数就是22,而正确的420美分只需要18个(16个25美分+2个10美分)。
快速解决方案:用round()函数修正精度
解决方法很简单:不要直接强制转换浮点数到整数,而是用round()函数对金额*100的结果四舍五入,确保得到正确的美分数量。
修正后的代码示例
#include <stdio.h> #include <math.h> // 必须包含这个头文件才能使用round() int main(void) { float amount; do { printf("Change owed: "); scanf("%f", &amount); } while (amount < 0); // 关键:用round()确保转换为正确的整数美分 int cents = round(amount * 100); int coins = 0; // 计算硬币数量的逻辑不变 while (cents >= 25) { coins++; cents -= 25; } while (cents >= 10) { coins++; cents -= 10; } while (cents >= 5) { coins++; cents -= 5; } while (cents >= 1) { coins++; cents -= 1; } printf("%d\n", coins); return 0; }
更严谨的思路:全程用整数处理
如果你想彻底避免浮点数问题,还有一个更稳妥的方法:直接让用户输入美分数量,或者读取输入的字符串后手动解析成整数美分(比如把"4.20"拆成4美元和20美分,合计420美分)。不过对于CS50的这个题目,用round()已经完全能解决问题了。
内容的提问来源于stack exchange,提问作者user9559752
相关产品推荐
相关产品推荐

