Python实现cad_cashier加拿大找零函数遇输入验证错误,求修正
问题:加拿大元找零函数修正
需求说明
编写函数cad_cashier(price, payment),输入两个带两位小数的非负实数(payment≥price,且payment的第二位小数为0或5),代表加拿大元的价格与付款金额,需返回保留两位小数的找零金额(找零需四舍五入至最近5分)。
原代码及问题
用户尝试的代码:
def cad_cashier(price, payment): if not (price.is_integer() and payment.is_integer()): return "Invalid input: Price and payment must have two decimal places." change_in_pennies = int((payment - price) * 100) change_in_pennies = round(change_in_pennies / 5) * 5 change_in_dollars = change_in_pennies / 100 return round(change_in_dollars, 2)
运行结果:
>>> cad_cashier(10.58,11) 'Invalid input: Price and payment must have two decimal places.'
预期输出为0.4,代码存在逻辑错误需要修正。
错误原因
- 输入验证逻辑完全错误:原代码用
price.is_integer() and payment.is_integer()判断输入是否合法,这个条件是检查输入是否为整数(无小数部分),但需求明确要求输入是带两位小数的数,比如10.58(两位小数)、11可视为11.00(两位小数),原判断直接将合法输入判定为非法,导致错误提示。 - 浮点数精度隐患:直接用
int((payment - price)*100)转换成分数时,可能因浮点数精度问题出现偏差(比如10.58*100可能得到1057.9999999999998,转int后变成1057),导致计算错误。
修正后的代码
def cad_cashier(price, payment): # 验证输入是否为带两位小数的非负实数 def has_two_decimals(num): num_str = "{0:.2f}".format(num) return len(num_str.split('.')[1]) == 2 if not (has_two_decimals(price) and has_two_decimals(payment)): return "Invalid input: Price and payment must have two decimal places." # 验证payment的第二位小数是0或5 payment_str = "{0:.2f}".format(payment) second_decimal = payment_str.split('.')[1][1] if second_decimal not in ('0', '5'): return "Invalid input: Payment's second decimal must be 0 or 5." # 转换为整数分,避免浮点数精度问题 price_cents = round(price * 100) payment_cents = round(payment * 100) change_cents = payment_cents - price_cents # 四舍五入到最近的5分 change_cents = round(change_cents / 5) * 5 # 转换为元并保留两位小数 change_dollars = change_cents / 100 return round(change_dollars, 2)
测试验证
运行cad_cashier(10.58,11)会返回0.4,符合预期:
- 11元对应1100分,10.58元对应1058分,差值为42分
- 42分四舍五入到最近的5分是40分,即0.4元
关键修正点
- 替换错误的输入验证逻辑:用字符串格式化方式判断是否存在两位小数,避免浮点数精度干扰
- 新增
payment第二位小数的合法性验证,符合需求要求 - 用
round(num * 100)转换成分数,规避浮点数直接相乘的精度丢失问题 - 保留找零四舍五入至5分的核心逻辑
内容的提问来源于stack exchange,提问作者AleSha
相关产品推荐
相关产品推荐

