Python - 二次方程极值
Python - Quadratic Equatin Extreme numbers
我写了代码来求解Python中的二次方程。但它有非常大的数字错误,如“1e10”和“-1e10”。是否有数值解或 python 解?
enter code here
import math
import cmath
def solve_quad(b, c):
a = 1
D = b*b - 4*a*c
if (D > 0):
x1 = (-b - math.sqrt(D)) / (2*a)
x2 = (-b + math.sqrt(D)) / (2*a)
elif D == 0:
x1 = (-b - math.sqrt(D)) / (2*a)
x2 = x1
else:
x1 = (-b - cmath.sqrt(D)) / (2*a)
x2 = (-b + cmath.sqrt(D)) / (2*a)
return x1, x2
print(solve_quad(1e10, 4))
输出:
(-10000000000.0, 0.0)
您可能遇到浮点精度问题。您可以使用 Decimal 或其他类似的库来获得更好的精度并避免这种情况:
from decimal import *
def solve_quad(b, c):
a = 1
D = b*b - 4*a*c
if (D > 0):
x1 = (-b - D.sqrt()) / (2*a)
x2 = (-b + D.sqrt()) / (2*a)
elif D == 0:
x1 = (-b - D.sqrt()) / (2*a)
x2 = x1
else:
x1 = (-b - D.sqrt()) / (2*a)
x2 = (-b + D.sqrt()) / (2*a)
return x1, x2
print(solve_quad(Decimal(1e10), Decimal(4)))
这是一个非常古老且经常重复的话题。让我们再解释一次。您使用二项式定理来避免数值不稳定性。
作为第一个根,您选择 -b
的符号与平方根前的符号相同的符号。
if D>0:
SD = D**0.5;
if b > 0: SD = -SD
x1 = (-b+SD) / (2*a)
然后对于第二个根,您使用公式
(-b-SD) / (2*a)
= (b^2-SD^2) / (2*a*(-b+SD))
= 4*a*c / (2*a*(-b+SD))
= (2*c) / (-b+SD)
得到
x2 = (2*c) / (-b+SD)
在其他情况下,不会发生使用此过程避免的灾难性取消。
这完全避免了由于灾难性取消而导致的所有数值不稳定性。如果您想更进一步,您还可以尝试避免判别式计算中的潜在溢出。
我写了代码来求解Python中的二次方程。但它有非常大的数字错误,如“1e10”和“-1e10”。是否有数值解或 python 解?
enter code here
import math
import cmath
def solve_quad(b, c):
a = 1
D = b*b - 4*a*c
if (D > 0):
x1 = (-b - math.sqrt(D)) / (2*a)
x2 = (-b + math.sqrt(D)) / (2*a)
elif D == 0:
x1 = (-b - math.sqrt(D)) / (2*a)
x2 = x1
else:
x1 = (-b - cmath.sqrt(D)) / (2*a)
x2 = (-b + cmath.sqrt(D)) / (2*a)
return x1, x2
print(solve_quad(1e10, 4))
输出: (-10000000000.0, 0.0)
您可能遇到浮点精度问题。您可以使用 Decimal 或其他类似的库来获得更好的精度并避免这种情况:
from decimal import *
def solve_quad(b, c):
a = 1
D = b*b - 4*a*c
if (D > 0):
x1 = (-b - D.sqrt()) / (2*a)
x2 = (-b + D.sqrt()) / (2*a)
elif D == 0:
x1 = (-b - D.sqrt()) / (2*a)
x2 = x1
else:
x1 = (-b - D.sqrt()) / (2*a)
x2 = (-b + D.sqrt()) / (2*a)
return x1, x2
print(solve_quad(Decimal(1e10), Decimal(4)))
这是一个非常古老且经常重复的话题。让我们再解释一次。您使用二项式定理来避免数值不稳定性。
作为第一个根,您选择 -b
的符号与平方根前的符号相同的符号。
if D>0:
SD = D**0.5;
if b > 0: SD = -SD
x1 = (-b+SD) / (2*a)
然后对于第二个根,您使用公式
(-b-SD) / (2*a)
= (b^2-SD^2) / (2*a*(-b+SD))
= 4*a*c / (2*a*(-b+SD))
= (2*c) / (-b+SD)
得到
x2 = (2*c) / (-b+SD)
在其他情况下,不会发生使用此过程避免的灾难性取消。
这完全避免了由于灾难性取消而导致的所有数值不稳定性。如果您想更进一步,您还可以尝试避免判别式计算中的潜在溢出。