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

简易找零计算器出现浮点数精度异常问题求助

找零计算器浮点数计算异常的原因与解决方法

我正在开发一个基础Python找零计算器,通过cs50库获取float类型输入金额,计算应找零的quarters(25美分)、dimes(10美分)、nickels(5美分)和pennies(1美分)的总数量。但浮点数计算出现异常,例如输入0.41,减去0.25后得到0.15999999999999998这类奇怪数值,请问这是什么原因?

原代码:

import cs50

def get_cents():
    cents = cs50.get_float("Amount of cents owed: ")
    return cents

def calculate_quarters(cents):
    quarters = 0
    while cents >= 0.25:
        cents = cents - 0.25
        quarters += 1
    return quarters

def calculate_dimes(cents):
    dimes = 0
    while cents >= 0.10:
        cents = cents - 0.10
        dimes += 1
    return dimes

def calculate_nickels(cents):
    nickels=0
    while cents >= 0.05:
        cents = cents - 0.05
        nickels += 1
    return nickels

def calculate_pennies(cents):
    pennies= 0
    while cents >= 0.01:
        cents = cents - 0.01
        pennies += 1
    return pennies

# Ask how many cents the customer is owed
cents = get_cents()
print(cents)

# Calculate the number of quarters (25 cent) to give the customer
quarters = calculate_quarters(cents)
cents = cents - (quarters * 0.25)
print(cents)

#Calculate the number of dimes (10 cent) to give the customer
dimes = calculate_dimes(cents)
cents = cents - (dimes * 0.10)
print(cents)

# Calculate the number of nickels (5 cent) to give the customer
nickels = calculate_nickels(cents)
cents = cents - (nickels * 0.05)
print(cents)

# Calculate the number of pennies (1 cent) to give the customer
pennies = calculate_pennies(cents)
cents = cents - (pennies * 0.01)
print(cents)

# Sum coins
coins = (quarters + dimes + nickels + pennies)
print(cents)

# Print total number of coins to give the customer
print(coins)

问题原因

这是二进制浮点数的精度限制导致的问题。计算机用二进制存储浮点数,但十进制中的部分小数(比如0.1、0.05)无法被精确转换成二进制有限小数,只能存储近似值。当你输入0.41时,它在二进制中已经是一个近似值,减去0.25(可精确表示)后,剩余值自然也是带误差的近似值,表现为0.15999999999999998而非精确的0.16。

这类误差会干扰循环判断逻辑,比如本该触发cents >= 0.01的数值,可能因精度问题变成0.009999999999999998,导致少算一枚便士。

解决方案

最稳妥的处理方式是**将金额转换为整数(以美分为单位)**进行计算,整数在计算机中可精确存储,完全规避浮点数精度问题。

修改后的代码:

import cs50

def get_cents():
    # 获取美元金额,转换为整数美分(用round处理输入误差)
    dollars = cs50.get_float("Amount owed (in dollars): ")
    cents = round(dollars * 100)
    return cents

def calculate_quarters(cents):
    return cents // 25

def calculate_dimes(cents):
    return cents // 10

def calculate_nickels(cents):
    return cents // 5

def calculate_pennies(cents):
    return cents // 1

# 获取以美分为单位的金额
cents = get_cents()
print(f"Total cents owed: {cents}")

# 计算各硬币数量并扣除对应金额
quarters = calculate_quarters(cents)
cents -= quarters * 25
print(f"Remaining cents after quarters: {cents}")

dimes = calculate_dimes(cents)
cents -= dimes * 10
print(f"Remaining cents after dimes: {cents}")

nickels = calculate_nickels(cents)
cents -= nickels * 5
print(f"Remaining cents after nickels: {cents}")

pennies = calculate_pennies(cents)
cents -= pennies * 1
print(f"Remaining cents after pennies: {cents}")

# 统计总硬币数
total_coins = quarters + dimes + nickels + pennies
print(f"Total coins to give: {total_coins}")

修改说明

  1. 输入转换:将美元金额乘以100后取整,转为整数美分;用round()处理输入时的微小精度误差(比如0.41*100可能得到40.99999999999999,取整后得到正确的41)。
  2. 整数运算:用整除//直接计算硬币数量,替代循环累加,效率更高且无精度问题。
  3. 全程整数操作:彻底消除浮点数带来的精度误差,保证计算逻辑准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:10:39