You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

问题原因

  1. break语句提前终止循环:处理完一种面额的硬币后,break直接跳出了外层的while changeOwed > float(0)循环,程序不再处理剩余找零金额,因此只会统计最大面额的硬币数。
  2. 浮点数精度误差引发无限循环:如果去掉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)

改动说明

  1. 整数转换:把输入的美元金额乘以100后四舍五入,转换为整数美分,所有计算都用整数进行,完全避免浮点数精度问题。
  2. 移除break:去掉了循环内的break,让程序在每次处理完一种面额后,回到循环开头继续处理剩余的金额,直到change_cents为0时终止循环。
  3. 简化计算:整数除法可以直接用//代替math.floor(),更简洁高效;处理1美分时直接取剩余金额即可,无需除法。

内容的提问来源于stack exchange,提问作者user19894190

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 04:43:31