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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:50:27