C17:for循环变量行为异常,金额拆分逻辑不符合预期
金额拆分代码的两个核心问题:判断逻辑错误+浮点精度坑
你遇到的问题根源有两个,直接导致了面额匹配错误和看似随机的循环异常:
1. 判断条件写错了,漏掉了等额匹配的情况
你的代码里用Input/SizeBilletes[i] > 1作为判断条件,这会直接跳过「剩余金额恰好等于当前面额」的场景。比如输入1200,减去2张500后剩200,此时200/200 = 1,不满足>1的要求,程序直接跳过200面额,转而处理100面额,自然输出2张100的结果。
2. float的精度误差在搞鬼
用float存金额是大忌,单精度浮点数无法精确表示所有整数,比如200可能被存成199.99998这种近似值。哪怕你改了判断条件,这种精度误差也可能让程序误以为剩余金额不够当前面额,进而跳过;甚至会让你误以为循环变量i的变化随机,实际上是金额值的异常导致逻辑执行不符合预期。
修正方案
临时过渡:改判断条件+优化浮点处理
如果暂时必须用float,先把判断条件改成Input >= SizeBilletes[i] - 1e-6(用极小值抵消精度误差),同时把floor()换成round(),避免因为精度损失导致的向下取整错误:
#include <stdio.h> #include <math.h> int main() { float Input; scanf("%f", &Input); int SizeBilletes[7] = {500,200,100,50,20,10,5}; for(int i=0; i<7; i++){ // 加个极小值缓冲,抵消浮点精度误差 if(Input >= SizeBilletes[i] - 1e-6){ // 用round替代floor,避免精度损失导致的取整错误 int a = round(Input / SizeBilletes[i]); Input -= a * SizeBilletes[i]; printf("[%d] en Billetes de %d\n", a, SizeBilletes[i]); } } }
推荐方案:改用整数存储金额(彻底解决精度问题)
金额是精确数值,最好转成最小单位(比如分)用整数存储,从根源上避免浮点误差。比如用户输入1200.50元,就存成120050分:
#include <stdio.h> #include <math.h> int main() { float input_float; scanf("%f", &input_float); // 转成分,用long long防止金额过大溢出 long long Input = llround(input_float * 100); // 面额数组存对应的分值,另一个数组存显示用的元面额 int billete_values[7] = {50000,20000,10000,5000,2000,1000,500}; int billete_labels[7] = {500,200,100,50,20,10,5}; for(int i=0; i<7; i++){ if(Input >= billete_values[i]){ int count = Input / billete_values[i]; Input -= count * billete_values[i]; printf("[%d] en Billetes de %d\n", count, billete_labels[i]); } } // 可选:处理剩余的分币 if(Input > 0){ printf("[%lld] en Centavos\n", Input); } return 0; }
额外说明
- 为什么
Input %= SizeBill[i]报错?因为%是整数取模运算符,float类型不能直接用,所以编译失败。 - 用一堆if语句能正常运行,是因为你手动逐个判断时可能默认处理了「等于面额」的情况,且单次判断的精度误差影响小,但这种写法冗余,加新面额时要改一堆代码,扩展性极差。
内容的提问来源于stack exchange,提问作者MMarqueto
相关产品推荐
相关产品推荐

