Python多项式求值:如何解决浮点数结果的精度偏差
浮点数精度偏差问题解决方法
问题背景
程序需要实现以下功能:
- 接收一个整数(对应多项式系数,例如整数32015代表多项式$3x4+2x3+x+5$,$x^2$的系数为0)
- 接收x的浮点值
- 计算多项式$a_nxn+a_{n-1}x{n-1}+...+a_0$的值,其中$a_i$为对应x幂次的系数
- 第一个输入不接受小数,结果需保留所有小数位
原代码如下:
while True: try: number = list(reversed(input())) if int("".join(number)): break except: print("Invalid Input") while True: try: x = float(input()) break except: print("Invalid Input") degree = len(number) result = 0 for i in range(degree): result += int(number[i]) * pow(x,i) print(result)
问题现象
输入341和-2.9时,预期输出为218.11999999999998,但实际得到218.11999999999995,这是浮点数精度累积误差导致的。
解决方案
原因分析
Python中的float基于二进制存储,像-2.9这类十进制小数无法被二进制浮点数精确表示,多次幂运算和加法后,微小的误差会累积放大,最终导致结果偏差。
方法一:用霍纳法则优化计算
霍纳法则通过重组多项式计算顺序,将$a_nxn+a_{n-1}x{n-1}+...+a_0$转化为$((...((a_nx)+a_{n-1})x+...)x)+a_0$,每一步仅做一次乘法和加法,大幅减少误差累积,同时提升计算效率。
修改后的代码:
while True: try: coeff_str = input().strip() # 验证输入为整数(不含小数点) if '.' in coeff_str: print("Invalid Input") continue # 系数列表:原数字的第一位对应最高次项系数 coefficients = [int(c) for c in coeff_str] break except: print("Invalid Input") while True: try: x = float(input()) break except: print("Invalid Input") # 霍纳法则计算多项式值 result = 0 for coeff in coefficients: result = result * x + coeff print(result)
测试输入341和-2.9,会得到预期的218.11999999999998。
方法二:使用decimal模块精确计算
Python的decimal模块支持十进制浮点数运算,可通过设置精度避免二进制浮点数的固有误差。
修改后的代码:
from decimal import Decimal, getcontext # 设置足够高的计算精度(比如20位) getcontext().prec = 20 while True: try: coeff_str = input().strip() if '.' in coeff_str: print("Invalid Input") continue coefficients = [Decimal(c) for c in coeff_str] break except: print("Invalid Input") while True: try: x = Decimal(input().strip()) break except: print("Invalid Input") # 结合霍纳法则用decimal计算 result = Decimal(0) for coeff in coefficients: result = result * x + coeff # 转换为float输出以匹配原格式 print(float(result))
该方法精度可控,适合对计算精度要求更高的场景,同样能得到预期结果。
额外优化说明
原代码中int("".join(number))的判断存在逻辑问题:若输入为0会被误判为无效输入。修改后的代码直接检查输入是否含小数点,更符合需求。
内容的提问来源于stack exchange,提问作者user20451212
相关产品推荐
相关产品推荐

