Python - Квадрати c Экватин Экстремальные числа - PullRequest
1 голос
/ 05 апреля 2020

Я написал код для решения квадратного c уравнения в 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)

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

Это очень старый и часто повторяемый топи c. Давайте объясним это еще раз. Вы используете биномиальную теорему, чтобы избежать числовой нестабильности.

В качестве первого root вы выбрали тот, в котором знак -b и знак перед квадратом root совпадают.

if D>0:
    SD = D**0.5;
    if b > 0: SD = -SD
    x1 = (-b+SD) / (2*a)

Затем для второго root вы используете формулу

(-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)

В других случаях отмены катастрофы c, которых избегают с эта процедура не выполняется.

Это полностью исключает любую числовую нестабильность из-за отмены катастрофы c. Если вы хотите go дальше, вы также можете попытаться избежать потенциального переполнения при вычислении дискриминанта.

0 голосов
/ 05 апреля 2020

Вероятно, у вас проблемы с точностью с плавающей запятой. Вы можете использовать десятичную или другую подобную библиотеку, чтобы повысить точность и обойти это:

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)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...