CS50 Week6 PSET Cash程序while循环执行异常问题求助
找零硬币计算程序的问题修复
问题背景
我正在实现一个找零程序,输入找零金额后返回最少数量的硬币(面额为25美分、10美分、5美分、1美分)。输入格式的错误处理已经完成,但计算逻辑出了问题:
- 测试非单一面额可整除的金额(如0.4、4.2、0.15等)时,程序仅统计最大面额的硬币数(比如4.2只算16枚25美分,漏掉2枚10美分;0.15只算1枚10美分,剩下的5美分没统计)
- 如果移除循环里的
break语句,只有单一面额可整除的金额能正常计算,其他金额会陷入无限循环
原代码
import math while True: try: changeOwed = float(input("Change owed:")) while changeOwed < 0: changeOwed = float(input("Change owed:")) break except ValueError: continue coinCount = 0 while changeOwed > float(0): if changeOwed >= 0.25: quartersNeeded = math.floor(changeOwed/0.25) coinCount = coinCount + quartersNeeded changeOwed = changeOwed - (quartersNeeded*0.25) elif changeOwed >= 0.10: dimesNeeded = math.floor(changeOwed/0.1) coinCount = coinCount + dimesNeeded changeOwed = changeOwed - (dimesNeeded*0.1) elif changeOwed >= 0.05: NickelsNeeded = math.floor(changeOwed/0.05) coinCount = coinCount + NickelsNeeded changeOwed = changeOwed - (NickelsNeeded*0.05) else: PenniesNeeded = math.floor(changeOwed/0.01) coinCount = coinCount + PenniesNeeded changeOwed = changeOwed - (PenniesNeeded*0.01) break print(coinCount)
问题原因
- break语句提前终止循环:处理完一种面额的硬币后,
break直接跳出了外层的while changeOwed > float(0)循环,程序不再处理剩余找零金额,因此只会统计最大面额的硬币数。 - 浮点数精度误差引发无限循环:如果去掉
break,浮点数的二进制存储特性会导致精度问题——比如0.1、0.05这类十进制小数在二进制里是无限循环的,计算后changeOwed永远无法精确等于0,循环会一直执行下去。
修复方案
核心改动点
- 移除循环内的
break,让程序能反复处理剩余找零金额 - 将金额转换为整数(以美分为单位),彻底规避浮点数精度问题
修复后的代码
import math while True: try: # 输入金额后转换为整数美分,避免浮点数精度问题 changeOwed = float(input("Change owed:")) while changeOwed < 0: changeOwed = float(input("Change owed:")) # 转换为整数美分,四舍五入处理浮点精度问题 change_cents = round(changeOwed * 100) break except ValueError: continue coinCount = 0 # 用整数美分进行计算 while change_cents > 0: if change_cents >= 25: quartersNeeded = change_cents // 25 coinCount += quartersNeeded change_cents -= quartersNeeded * 25 elif change_cents >= 10: dimesNeeded = change_cents // 10 coinCount += dimesNeeded change_cents -= dimesNeeded * 10 elif change_cents >= 5: nickelsNeeded = change_cents // 5 coinCount += nickelsNeeded change_cents -= nickelsNeeded * 5 else: penniesNeeded = change_cents coinCount += penniesNeeded change_cents = 0 print(coinCount)
改动说明
- 整数转换:把输入的美元金额乘以100后四舍五入,转换为整数美分,所有计算都用整数进行,完全避免浮点数精度问题。
- 移除break:去掉了循环内的
break,让程序在每次处理完一种面额后,回到循环开头继续处理剩余的金额,直到change_cents为0时终止循环。 - 简化计算:整数除法可以直接用
//代替math.floor(),更简洁高效;处理1美分时直接取剩余金额即可,无需除法。
内容的提问来源于stack exchange,提问作者user19894190
相关产品推荐
相关产品推荐

