2009-05-22 3 views
6

Я пытаюсь написать функцию в C++, которая решает для X, используя квадратичное уравнение. Это то, что я написал вначале, что, кажется, работает до тех пор, пока не существует комплексных чисел для ответа:Решите квадратичное уравнение в C++

float solution1 = (float)(-1.0 * b) + (sqrt((b * b) - (4 * a * c))); 
solution1 = solution1/(2*a); 

cout << "Solution 1: " << solution1 << endl; 

float solution2 = (float)(-b) - (sqrt((b*b) - (4 * a * c))); 
solution2 = solution2/(2*a); 
cout << "Solution 2: " << solution2; 

Если, например, я использую уравнение: х^2 - х - 6, я правильное решение 3, -2.

Мой вопрос заключается в том, как бы мне объяснить комплексных чисел .... например, учитывая уравнение:

х^2 + 2x + 5

Решая вручную, я хотел бы получить -1 + 2i, -1 - 2i.

Ну, я думаю, что два вопроса, могу ли я написать выше, а также сделать его учет для комплексного числа?

Спасибо за помощь!

+3

Остальные ребята при условии хороших ответов так нет причин для меня не пытаться затмить их;) Тем не менее, если вы хотите получить более общее решение уравнения ах^2 + Ьх + с = 0, помните, что а = = 0 должно быть допустимым значением. Это приведет к делению нуля, поэтому вы должны позаботиться об этом случае отдельно. В этом случае это будет означать, что вы останетесь с линейным уравнением с одним корнем. Приветствия! – ralphtheninja

+0

Вы подразумеваете, что вас беспокоят сложные корни, но как насчет комплексных коэффициентов в исходном уравнении? –

+1

Сложные коэффициенты требуют другого подхода полностью. Итак, это будет следующий вопрос :) * отмахивается и готовит ответ перед рукой * – ralphtheninja

ответ

8

Что-то, как это будет работать:

struct complex { double r,i; } 
struct pair<T> { T p1, p2; } 

pair<complex> GetResults(double a, double b, double c) 
{ 
    pair<complex> result={0}; 

    if(a<0.000001) // ==0 
    { 
    if(b>0.000001) // !=0 
     result.p1.r=result.p2.r=-c/b; 
    else 
     if(c>0.00001) throw exception("no solutions"); 
    return result; 
    } 

    double delta=b*b-4*a*c; 
    if(delta>=0) 
    { 
    result.p1.r=(-b-sqrt(delta))/2/a; 
    result.p2.r=(-b+sqrt(delta))/2/a; 
    } 
    else 
    { 
    result.p1.r=result.p2.r=-b/2/a; 
    result.p1.i=sqrt(-delta)/2/a; 
    result.p2.i=-sqrt(-delta)/2/a; 
    } 

    return result; 
} 

Таким образом, вы получите результаты, таким же образом, как для реальных и сложных результатов (реальные результаты только имеют мнимую часть набора 0). Будет выглядеть даже красивее!

редактирование: исправлено для дельта-вещи и добавлена ​​проверка на вырожденные случаи, такие как a = 0. Бессонные ночи ftl!

+0

Если sqrt преуспевает, результат равен> = 0. И если аргумент отрицательный, ваша программа выйдет из строя. Вы должны сначала проверить знак и вычислить sqrt. Если знак будет отрицательным, вы должны установить result.first.i = + sqrt (4 * a * c-b * b)/2/a. (Зачем определять свой собственный тип, если есть прекрасная std :: pair ?) – MSalters

+0

должен быть delta = b * b-4 * a * c и принимать sqrt только при delta> = 0. delta = 0 или a = 0 являются действительными случаями, когда мы имеем один корень. Что делать, если a = b = 0 и c = 1? –

+0

Что делать? Это не квадратичная функция, и часть/2/a не сработает. Это работает достаточно хорошо, если delta = 0, за исключением того, что tou вернет тот же результат дважды. – MSalters

4

У вас более или менее это есть, просто проверьте, не является ли часть, находящаяся внутри квадратного корня отрицательной, а затем отслеживайте это отдельно в своих сокращениях.

3

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

#inlcude <float.h> 
if (fabs(a) < FLT_EPSILON) 
    then a is considered 0 
3

Вы можете в основном просто использовать std::complex<float> вместо float, чтобы получить поддержку комплексных чисел.

1

перекреста идею из Blindy:

typedef std::complex<double> complex; 
using std::pair; 
pair<complex> GetResults(double a, double b, double c) 
{ 
    double delta=(b*b-4*a*c); 
    double inv_2a = 1/2/a; 
    if(delta >= 0) { 
    double root = sqrt(delta); 
    return std::make_pair(
     complex((-b-root)*inv_2a), 
     complex((-b+root)*inv_2a); 
    } else { 
    double root = sqrt(-delta); 
    return std::make_pair(
     complex(-b*inv_2a, -root*inv_2a)), 
     complex(-b*inv_2a, +root*inv_2a))); 
    } 
} 
20

Важное замечание для всего этого. Решения, показанные в этих ответах и ​​в исходном вопросе, не являются надежными.

Хорошо известное решение (-b + - SQRT (б^2 - 4ac))/2a, как известно, не надежными в вычислениях при переменного тока очень мала compered к б^2, потому что один вычитает два очень близких значения. Лучше использовать меньшее известное решение 2c/(-b - + sqrt (b^2 -4ac)) для другого корня.

надежное решение может быть рассчитана как:

temp = -0.5 * (b + sign(b) * sqrt(b*b - 4*a*c); 
x1 = temp/a; 
x2 = c/temp; 

Использование знака (б) гарантирует, что мы не вычитая два одинаковых значения.

Для ОП, измените это для сложных номеров, как показано на других плакатах.

+1

+1 это значительно вычислительно более устойчиво, чем '(-b +/- sqrt (b * b - 4 * a * c))/(2a)'. BTW: поскольку «temp» может быть 0.0, обычно требуется предварительная проверка. (например, a, b, c = 1,0,0). – chux

+0

'temp' может быть только 0, если' b' равно 0 –

-1

Я пробовал программу, не используя заголовок «math.h», а также пробовал использовать другую логику ... но моя программа может отвечать только на квадратичные уравнения, которые имеют коэффициент «x квадрат» как один ..... и где коэффициент «х» может быть выражен как добавление двух чисел, которые являются факторами постоянного члена. например. x квадрат + 8x + 16; x квадрат + 7x + 12; и т.д. здесь 8 = 4 + 4 & 16 = 4 * 4; здесь коэффициент х может быть выражен как сложение двух чисел, которые являются факторами постоянного члена 16 ... Я сам не полностью доволен, но попробовал что-то другое, не используя формулу для решения квадратного уравнения. код есть;

 #include<iostream.h> 
     #include<conio.h> 
     class quadratic 
       { 
       int b,c ; 
       float l,k; 
       public: 
       void solution(); 
       }; 
     void quadratic::solution() 
      { 
       cout<<"Enter coefficient of x and the constant term of the quadratic eqn where coefficient of x square is one"; 
       cin>>b>>c; 

       for(l=1;l<b;l++) 
        { 
        for(k=1;k<b;k++) 
        { 
        if(l+k==b&&l*k==c) 
         { 
          cout<<"x="<<-l<<"\t"<<"or"<<"\t"<<"x="<<-k; 
          cout<<"\n"; 
         } 
        } 
       } 
      } 
       void main() 
       { 
        quadratic a; 
        clrscr(); 
        a.solution(); 
        getch(); 
       } 
Смежные вопросы