【发布时间】:2021-03-12 01:31:36
【问题描述】:
我正在为我的编程课进行 C 练习,我发现某些计算会导致舍入错误,进而影响逻辑语句。请看下面代码的最后两行:
if (bmi_result < 18.5)
printf("Your BMI is %.1f and you might be underweight.\n\n", bmi_result);
else if (bmi_result >= 18.5 && bmi_result <= 24.9)
printf("Your BMI is %.1f and you have a normal weight.\n\n", bmi_result);
else if (bmi_result >= 25.0 && bmi_result <= 29.9)
printf("Your BMI is %.1f and you might be overweight.\n\n", bmi_result);
else if (bmi_result >= 30.0)
printf("Your BMI is %.1f and you might be obese.\n\n", bmi_result);
BMI 计算为 double bmi_result = 703 * weight / (height * height); 如果我使用 65 (in) 的身高和 180 (lb) 的体重,结果为 29.9502,则 if/else 语句会忽略此值。
不幸的是,我必须完全按照书面要求遵循 BMI 参数,因为这是此问题的要求。使用 round() 可以解决部分问题(例如,在我给出的特定情况下),但我会失去其他值的精度。
是否有人对如何解决这个问题有任何建议,并确保程序对任何输入都能准确运行?是否有另一个类似于 round() 的函数允许您指定舍入到特定值(最接近的十分之一)?
【问题讨论】:
-
问题在于,由于浮点数通常是二进制的,像
24.9这样的数字可能无法精确表示。那么对于24.901,“四舍五入到最接近的十分之一”应该返回什么? -
通常您会改为更改比较值。所以如果
bmi_result <= 24.95你输出“正常”,如果bmi_result > 24.95你输出overweight。 -
将
10 * bmi计算为整数,使用整数计算和四舍五入,那么您就不必担心浮点怪癖了。 -
比较应该是
if(r<18.5){} else if (r<25.0){} else if (r<30.0){} else {}这样,浮点数的精度不足无关紧要。 -
@NateEldredge 我猜它应该返回与 29.0 相同的浮点数?我对计算机中二进制算术的实现不太熟悉。但是本着 dxiv 评论的精神,我做了 rounded_bmi_result = round(10 * bmi_result)/10 并且在逻辑上和实践中看起来都很好。如果您不介意解释,那么此解决方案与您所说的有什么差异。
标签: c rounding-error