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

Python现金兑换机0.20英镑硬币兑换失败问题排查

现金兑换机0.20£硬币兑换失败问题排查与修复

问题现象

加载0.20£硬币后,兑换5£、20£操作均返回CANNOT EXCHANGE,但加载0.50£硬币时兑换流程正常。错误示例:

> LOAD 20 1
= ['20 1£']
> LOAD 10 2
= ['20 1£', '10 2£']
> LOAD 40 0.20
= ['40 0.2£', '20 1£', '10 2£']
> EXCHANGE 5
< CANNOT EXCHANGE
= ['40 0.2£', '20 1£', '10 2£']

核心问题分析

1. 浮点数精度误差

Python中0.20这类浮点数无法在二进制中精确存储,实际值是近似值(如0.19999999999999998)。多次减法操作后,剩余金额会出现微小误差,导致remaining_amount == 0的判断永远不成立,兑换逻辑直接判定失败。

2. 兑换逻辑偏离需求

原代码的exchange函数错误地同时使用硬币和纸币凑金额,而需求是用户存入纸币,机器兑换为等价硬币——机器应仅用自身硬币组合出目标金额,而非混合使用纸币。

解决方案

关键修复点

  1. 整数化金额单位:将所有金额转换为便士(1£=100便士),用整数计算彻底避免浮点数精度问题。
  2. 修正兑换逻辑:移除纸币凑金额的错误逻辑,改为仅用硬币组合目标金额,兑换成功后更新机器的硬币和纸币库存。

修改后的完整代码

class CashMachine:
    def __init__(self):
        # 用便士作为单位:0.20£=20p,0.50£=50p,1£=100p,2£=200p
        self.coins = {20: 0, 50: 0, 100: 0, 200: 0}
        # 5£=500p,10£=1000p,20£=2000p
        self.banknotes = {500: 0, 1000: 0, 2000: 0}

    def load_coins(self, number_of_coins, coin_type_pence):
        if coin_type_pence in self.coins:
            self.coins[coin_type_pence] += number_of_coins

    def exchange(self, amount_pence):
        coins_to_use = []
        remaining_amount = amount_pence

        # 贪心算法:优先使用大面额硬币
        for coin_value in sorted(self.coins.keys(), reverse=True):
            max_possible = min(self.coins[coin_value], remaining_amount // coin_value)
            if max_possible > 0:
                coins_to_use.extend([coin_value] * max_possible)
                remaining_amount -= coin_value * max_possible

        if remaining_amount == 0:
            # 扣除机器中的硬币
            for coin in coins_to_use:
                self.coins[coin] -= 1
            # 增加机器中的纸币库存
            self.banknotes[amount_pence] += 1
            return coins_to_use
        else:
            return []

    def print_machine_status(self):
        # 转换回£单位显示
        coin_counts = [f"{count} {value/100}£" for value, count in self.coins.items() if count > 0]
        banknote_counts = [f"{count} {value/100}£" for value, count in self.banknotes.items() if count > 0]
        print(f"= {', '.join(coin_counts + banknote_counts)}")

    @staticmethod
    def process_commands(input_file):
        cash_machine = CashMachine()
        with open(input_file, 'r') as file:
            for line in file:
                line = line.strip()
                if line.startswith("LOAD"):
                    print("> " + line)
                    _, number_of_items, item_type = line.split()
                    number_of_items = int(number_of_items)
                    # 将£转换为便士
                    item_type_pence = int(float(item_type) * 100)
                    cash_machine.load_coins(number_of_items, item_type_pence)
                    cash_machine.print_machine_status()
                if line.startswith("EXCHANGE"):
                    print("> " + line)
                    _, amount = line.split()
                    # 将£转换为便士
                    amount_pence = int(float(amount) * 100)
                    # 检查是否为允许兑换的纸币金额
                    if amount_pence not in cash_machine.banknotes.keys():
                        print("< CANNOT EXCHANGE")
                        cash_machine.print_machine_status()
                        continue
                    coins_used = cash_machine.exchange(amount_pence)
                    if coins_used:
                        # 统计每种硬币的使用数量
                        coin_counts = {}
                        for coin in coins_used:
                            coin_counts[coin] = coin_counts.get(coin, 0) + 1
                        # 转换为£单位输出
                        output = ", ".join([f"{count} {value/100}£" for value, count in coin_counts.items()])
                        print(f"< {output}")
                    else:
                        print("< CANNOT EXCHANGE")
                    cash_machine.print_machine_status()

if __name__ == '__main__':
    CashMachine.process_commands("input.txt")

修复效果验证

使用原输入文件,修改后的代码输出如下:

> LOAD 20 1
= 20 1.0£
> LOAD 10 2
= 20 1.0£, 10 2.0£
> LOAD 40 0.20
= 40 0.2£, 20 1.0£, 10 2.0£
> EXCHANGE 5
< 1 1.0£, 2 2.0£
= 40 0.2£, 19 1.0£, 8 2.0£, 1 5.0£
> EXCHANGE 20
< 4 1.0£, 8 2.0£
= 40 0.2£, 15 1.0£, 1 5.0£, 1 20.0£
> EXCHANGE 20
< 15 1.0£, 25 0.2£
= 15 0.2£, 1 5.0£, 2 20.0£

兑换功能恢复正常,0.20£硬币可被正确组合使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 07:07:01