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

Python中分数与浮点数计算精度丢失问题的技术求助

解决SymPy与Fractions库混合计算时的浮点数精度丢失问题

你的推测完全正确——问题出在浮点数的二进制表示局限性:像10/3这类分数无法用二进制浮点数精确表示,存储的是近似值,后续替换到表达式中再经SymPy解析时,这些近似误差会被放大,导致结果出现8.0000000000000003、-0.9999999999999999这类不精确值。

核心解决方案:用精确分数类型替代浮点数

直接在矩阵中使用精确分数(而非浮点数),确保所有数值都是精确表示的,从根源避免精度丢失。有两种可行方式:

方式1:使用fractions.Fraction定义矩阵元素

把矩阵中所有分数形式的浮点数替换为Fraction(分子, 分母),这样存储的是精确分数对象,转成字符串时会输出"10/3"而非浮点数近似值。

修改后的矩阵定义:

new_matrix_aux = [['X',   'B', 'X1', 'X2', 'X3', 'X4', 'X5', 'U1', 'U2'], 
                  ['X2', Fraction(10,3),    0,    1,  Fraction(2,3),  Fraction(1,3), Fraction(-2,3), Fraction(-1,3),  Fraction(2,3)],  
                  ['X1',  Fraction(4,3),    1,    0,  Fraction(2,3), Fraction(-2,3),  Fraction(1,3), Fraction(2,3), Fraction(-1,3)]]

方式2:使用SymPy内置的sp.Rational

SymPy本身提供了精确分数类型Rational,和SymPy的表达式解析更适配,用法和Fraction类似:

new_matrix_aux = [['X',   'B', 'X1', 'X2', 'X3', 'X4', 'X5', 'U1', 'U2'], 
                  ['X2', sp.Rational(10,3),    0,    1,  sp.Rational(2,3),  sp.Rational(1,3), sp.Rational(-2,3), sp.Rational(-1,3),  sp.Rational(2,3)],  
                  ['X1',  sp.Rational(4,3),    1,    0,  sp.Rational(2,3), sp.Rational(-2,3),  sp.Rational(1,3), sp.Rational(2,3), sp.Rational(-1,3)]]

修改后完整代码示例

import sympy as sp
from fractions import Fraction

new_matrix_aux = [['X',   'B', 'X1', 'X2', 'X3', 'X4', 'X5', 'U1', 'U2'], 
                  ['X2', Fraction(10,3),    0,    1,  Fraction(2,3),  Fraction(1,3), Fraction(-2,3), Fraction(-1,3),  Fraction(2,3)],  
                  ['X1',  Fraction(4,3),    1,    0,  Fraction(2,3), Fraction(-2,3),  Fraction(1,3), Fraction(2,3), Fraction(-1,3)]]

z_function = "Z = 1 * X1 + 2 * X2 + 3 * X3 + 0 * X4 + 0 * X5 + M * U1 + M * U2"


lista_de_operaciones_zj = []

for j in range(1, len(new_matrix_aux[0])):
    z = z_function
    for i in range(1, len(new_matrix_aux)):
        z = z.replace(new_matrix_aux[i][0], str(new_matrix_aux[i][j]))
    for k in range(1, len(new_matrix_aux[0])):
        z = z.replace(new_matrix_aux[0][k], '0')
    z = z.replace(z[0], z[0] + '_' + new_matrix_aux[0][j])
    lista_de_operaciones_zj.append(z)
    print(f'"{z}"')

variables, resultados = [], []

for operacion in lista_de_operaciones_zj:
    variable = operacion.split("Z_")[1].split(" = ")[0]
    variables.append(variable)
    expression = operacion.split("= ")[1]
    resultado = sp.sympify(expression)
    resultados.append(resultado)

output = [variables, resultados]
print(output)

运行结果

执行后会得到你期望的精确输出:

[['B', 'X1', 'X2', 'X3', 'X4', 'X5', 'U1', 'U2'], [8, 1, 2, 2, 0, -1, 0, 1]]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 17:54:55