为何调用gas_price(100.0,120.0)返回'3/4 Tank'而非'Half Tank'?
问题原因与解决方案
核心原因
你遇到的问题是浮点数精度误差导致的。虽然数学上(120.0 / 100.0) - 1等于0.2,但计算机在存储和计算浮点数时,可能会将这个值表示为一个非常接近0.2但略小于0.2的数(例如0.19999999999999996)。这个微小的误差会让代码触发percent < .2的条件分支,从而返回'3/4 Tank'而非预期的'Half Tank'。
解决方案
针对浮点数精度问题,你可以选择以下几种修复方式:
1. 引入误差范围(Epsilon)
通过定义一个极小的误差阈值,允许浮点数在这个范围内被视为相等:
def gas_price(previous, new): percent = (new / previous) - 1 epsilon = 1e-9 # 极小的误差容忍值 if abs(new - previous) < epsilon: decision = 'Full Tank' elif percent < 0.2 - epsilon: decision = '3/4 Tank' elif percent < 0.8 - epsilon: decision = 'Half Tank' elif percent < 1.0 - epsilon: decision = '1/4 Tank' else: decision = 'Go Home' return decision
2. 使用精确十进制计算
借助Python的decimal模块进行精确的十进制运算,彻底避免浮点数误差:
from decimal import Decimal def gas_price(previous, new): prev_dec = Decimal(str(previous)) new_dec = Decimal(str(new)) percent = (new_dec / prev_dec) - Decimal(1) if new_dec == prev_dec: decision = 'Full Tank' elif percent < Decimal('0.2'): decision = '3/4 Tank' elif percent < Decimal('0.8'): decision = 'Half Tank' elif percent < Decimal('1.0'): decision = '1/4 Tank' else: decision = 'Go Home' return decision
3. 调整条件判断顺序与逻辑
通过嵌套判断确保范围覆盖的准确性,减少精度误差的影响:
def gas_price(previous, new): percent = (new / previous) - 1 if new == previous: decision = 'Full Tank' elif percent < 0.8: # 先判断是否小于0.2,否则直接归为0.2~0.8区间 decision = '3/4 Tank' if percent < 0.2 else 'Half Tank' elif percent < 1.0: decision = '1/4 Tank' else: decision = 'Go Home' return decision
内容的提问来源于stack exchange,提问作者Miller25
相关产品推荐
相关产品推荐

