Python二次方程求解器Fraction报错及精确数值转换求助
问题解决:二次方程求解器的错误修复与精确输出实现
错误原因分析
- 运算顺序错误:你写的求根公式运算逻辑有误,正确的二次方程求根公式是
(-b ± √d)/(2a),但你的代码里是-b ± (√d/(2a)),缺少括号导致结果完全偏离预期。 - Fraction不支持复数:
cmath.sqrt()始终返回复数类型(哪怕判别式为正,结果也是x+0j的形式),而Fraction仅能处理字符串、整数、有理数等类型,无法解析复数,这就是抛出TypeError的直接原因。 - 不精确小数问题:直接用复数或浮点数计算会引入浮点精度误差,要输出精确结果,需要根据判别式的不同情况,用分数或根式形式表示。
修正后的代码
from fractions import Fraction import math def solver(a_entry, b_entry, c_entry): a = int(a_entry) b = int(b_entry) c = int(c_entry) d = b * b - 4 * a * c denominator = 2 * a if d > 0: # 判断判别式是否为完全平方数 sqrt_d_int = math.isqrt(d) if sqrt_d_int * sqrt_d_int == d: # 实根且可化为最简分数 sol1 = Fraction(-b - sqrt_d_int, denominator) sol2 = Fraction(-b + sqrt_d_int, denominator) print(f"x₁ = {sol1}, x₂ = {sol2}") else: # 实根带根式,输出精确代数表达式 sol1 = f"(-{b} - √{d})/{denominator}" if denominator != 1 else f"-{b} - √{d}" sol2 = f"(-{b} + √{d})/{denominator}" if denominator != 1 else f"-{b} + √{d}" print(f"x₁ = {sol1}, x₂ = {sol2}") elif d == 0: # 重根,直接输出最简分数 sol = Fraction(-b, denominator) print(f"x = {sol}(重根)") else: # 复数根,拆分实部和虚部分别处理 abs_d = -d sqrt_abs_d_int = math.isqrt(abs_d) real_part = Fraction(-b, denominator) if sqrt_abs_d_int * sqrt_abs_d_int == abs_d: imag_part = Fraction(sqrt_abs_d_int, denominator) print(f"x₁ = {real_part} - {imag_part}i, x₂ = {real_part} + {imag_part}i") else: imag_expr = f"√{abs_d}/{denominator}" if denominator != 1 else f"√{abs_d}" print(f"x₁ = {real_part} - ({imag_expr})i, x₂ = {real_part} + ({imag_expr})i") # 测试用例 solver(1, 2, 3) # 复数根案例 solver(1, -5, 6) # 可化为分数的实根案例 solver(2, 4, 2) # 重根案例 solver(1, 0, -2) # 带根式的实根案例
代码说明
- 修正运算顺序:将分子部分
(-b ± √d)作为整体处理后再除以2a,确保求根公式逻辑正确。 - 分情况处理判别式:
- 正判别式:如果是完全平方数,直接用
Fraction输出最简分数;否则保留根式,输出无精度损失的代数表达式。 - 零判别式:输出重根的最简分数形式。
- 负判别式:拆分实部(分数形式)和虚部(分数或根式形式),输出精确的复数表达式。
- 正判别式:如果是完全平方数,直接用
- 避免浮点误差:全程用整数和分数运算,仅在必要时保留根式符号,彻底解决不精确小数的问题。
内容的提问来源于stack exchange,提问作者Quantum Gamer
相关产品推荐
相关产品推荐

