Python银行小游戏浮点精度异常:求原因及非round函数解决方案
浮点数精度异常问题的原因与修复方案(无需使用round函数)
问题原因
这是二进制浮点数的固有精度缺陷导致的。计算机以二进制格式存储浮点数,但很多十进制小数(比如0.01、0.1这类)无法被二进制精确表示,只能存储一个无限接近的近似值。当你对这些近似值执行加减运算时,微小的误差会累积显现,最终输出像1487.3400000000001、3.259999999999991这类不符合预期的长数值。
修复方案
方案1:用整数存储货币单位(推荐)
货币计算最稳妥的方式是放弃浮点数,改用整数存储分(而非元),因为整数运算完全不会有精度损失。所有内部计算基于分进行,仅在需要显示时转换为元并格式化到两位小数。
修改money.py:
# 以分为单位存储,987.34元 = 98734分 bank_balance = 98734 wallet_balance = 50326
修改bank_deposit.py:
import money def bank_deposit(): while True: try: # 输入金额(元),转换为分(确保是整数) deposit_input = float(input("Deposit: ")) deposit = int(deposit_input * 100) # 验证条件:存款金额不低于1分,且不超过钱包余额 if deposit <= money.wallet_balance and deposit >= 1: print(f"Deposited ${deposit_input}!") break elif deposit == 0: print("You can't deposit $0!") continue else: # 显示钱包余额时转成元格式 print(f"You haven't got enough money in your pockets! You only have {money.wallet_balance / 100:.2f}") continue except ValueError: print("Input must be a valid number!") # 基于分执行加减运算 money.bank_balance += deposit money.wallet_balance -= deposit # 显示时转成元并格式化到两位小数 print(f"Bank account balance: {money.bank_balance / 100:.2f}") print(f"You have now ${money.wallet_balance / 100:.2f} in your pockets.") bank_deposit()
方案2:使用decimal模块精确计算
Python内置的decimal模块专门用于处理十进制精确运算,它用十进制而非二进制存储数值,从根源上避免浮点数精度问题。
修改money.py:
from decimal import Decimal # 用字符串初始化Decimal,确保精确性 bank_balance = Decimal("987.34") wallet_balance = Decimal("503.26")
修改bank_deposit.py:
import money from decimal import Decimal def bank_deposit(): while True: try: # 直接用Decimal接收输入,确保精确 deposit = Decimal(input("Deposit: ")) if deposit <= money.wallet_balance and deposit >= Decimal("0.01"): print(f"Deposited ${deposit}!") break elif deposit == Decimal("0"): print("You can't deposit $0!") continue else: print(f"You haven't got enough money in your pockets! You only have {money.wallet_balance}") continue except ValueError: print("Input must be a valid number!") # 执行精确的十进制运算 money.bank_balance += deposit money.wallet_balance -= deposit print(f"Bank account balance: {money.bank_balance}") print(f"You have now ${money.wallet_balance} in your pockets.") bank_deposit()
内容的提问来源于stack exchange,提问作者Lorak
相关产品推荐
相关产品推荐

