C语言套餐资费计算程序If条件分支运行不符合预期求助
C语言套餐费用对比程序异常问题解决方案
问题根源
你当前测试用例下两套套餐理论费用完全相等,本应进入di == 0的分支,却始终进入di > 0分支,核心原因是浮点数(double类型)的二进制存储机制会产生精度误差,禁止直接用==判断两个浮点数是否相等:
- 你代码中的运算都是浮点四则运算,理论上
an和bn的结果都是37.85,但实际运行时两个值会存在极小的偏差,比如一个是37.8500000001,另一个是37.8499999999,相减后得到的di是一个非常小的正数,因此触发了di>0的判断逻辑。
修复方案
引入一个极小的误差容限(比如1e-6,远小于你输出保留的4位小数的精度要求),判断两个浮点数差值的绝对值是否小于容限,即可认为二者相等。需要注意引入<math.h>头文件调用fabs()函数计算绝对值。
修改后的代码
#include <stdio.h> #include <math.h> // 引入头文件支持浮点数绝对值计算 int main(void) { double dt=162.0; //daytime double et=61.0; //evening time double wt=66.0; //weekend time double an=0.0; //last result A double bn=0.0; //last result B double di=0.0; //margin double a=0.0; double b=0.0; a = dt-100; b = dt-250; if(a<=0) { a=0; } if(b<=0) { b=0; } an=(a*0.25)+(et*0.15)+(wt*0.20); bn=(b*0.45)+(et*0.35)+(wt*0.25); printf("Plan A costs %.4f\n", an); printf("Plan B costs %.4f\n", bn); di=an-bn; const double EPS = 1e-6; // 误差容限 if(fabs(di) < EPS) // 替换原有的di == 0判断 { printf("Different $%.4f\n", di); printf("Plan A and B are the same price."); } else if(di > 0) { printf("Different $%.4f\n", di); printf("Plan B is cheapest."); } else { printf("Different $%.4f\n", di); printf("Plan A is cheapest."); } return 0; }
扩展优化建议
如果你的使用场景中所有时长、资费都是以分为最小单位的整数,也可以将所有数值放大100倍转为整数运算,完全规避浮点数精度问题,适合对精度要求极高的计费场景。
内容的提问来源于stack exchange,提问作者Jim Sjoo
相关产品推荐
相关产品推荐

