找零函数返回硬币字典未识别0.01//0.01=1.0,7.71找零0.01硬币数为0
浮点数精度导致找零函数未正确计算0.01硬币的问题
问题根源:浮点数的精度误差
Python里的浮点数用二进制存储,像0.1、0.2、0.71这类十进制小数没法被二进制精确表示,计算过程中会产生微小误差。
模拟change(7.71)的执行过程,关键看最后几步:
- 处理完0.2硬币后,理论上剩余0.01元,但实际浮点数计算得到的是约0.009999999999999987(因为0.21-0.2无法精确计算)。
- 后续处理0.1、0.05、0.02硬币时,剩余金额都小于这些面值,计数全为0。
- 最后处理0.01硬币时,剩余金额≈0.009999...,比0.01小,所以
money // 0.01结果是0,自然不会统计到1枚0.01硬币。
解决方案:用整数替代浮点数计算
避免浮点数误差的最优方式是把金额转成整数单位(比如分),所有计算用整数进行,最后再转回小数面值。修改后的代码如下:
def change(money): # 转换为分,彻底避免浮点数误差 cents = int(round(money * 100)) res = {} # 硬币面值(分)和对应的小数面值映射 coins = [ (200, 2.0), (100, 1.0), (50, 0.5), (20, 0.2), (10, 0.1), (5, 0.05), (2, 0.02), (1, 0.01) ] for cent_val, decimal_val in coins: count = cents // cent_val res[decimal_val] = count cents -= count * cent_val return res
调用change(7.71)会得到正确结果:
{2.0: 3, 1.0: 1, 0.5: 1, 0.2: 1, 0.1: 0, 0.05: 0, 0.02: 0, 0.01: 1}
额外说明
原函数的硬币面值切换逻辑本身没问题,但浮点数精度偏差会在计算中累积,尤其是涉及0.1、0.2这类无法精确表示的小数时,最终导致结果出错。用整数处理货币计算是行业通用做法,能彻底规避这类问题。
内容的提问来源于stack exchange,提问作者isma_moniz
相关产品推荐
相关产品推荐

