C++硬币计数程序美分计算少0.01的原因及解决方案
错误原因说明
- 浮点数精度丢失是核心问题:十进制下的0.1、0.05、0.01这类小数无法用二进制的
double类型精确存储,实际保存的是接近真实值的近似值。你给出的测试用例理论总和是6.22美元,但实际double类型计算后的存储值大概率是6.219999999999999这类略小于6.22的数。 - int强制转换的截断特性放大了问题:C++中将浮点数强转为int时会直接截断小数部分,不会做四舍五入。
6.219999999999999强转为int得到6没问题,但(6.219999999999999 -6)*100的计算结果是21.9999999999999,赋值给int类型的cents时会被直接截断为21,就出现了少1美分的问题。 - 你把
cents改成double类型后结果正确,只是因为cout输出double时默认会做四舍五入处理,21.9999999999999输出时被识别为22,本质上还是没有解决浮点数精度的底层问题,换其他测试用例依然可能出错。
推荐优化方案
处理货币类计算的标准做法是全程用整数操作,完全规避浮点数精度问题:
// 直接以美分为单位计算总金额 int total_cents = quarters * 25 + dimes * 10 + nickels *5 + pennies; dollars = total_cents / 100; cents = total_cents % 100;
上述代码没有任何精度损失,所有场景下都能得到正确结果。
内容的提问来源于stack exchange,提问作者undercoverk3vin
相关产品推荐
相关产品推荐

