Решить квадратное уравнение в C ++ - PullRequest
6 голосов
/ 22 мая 2009

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

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;

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

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

x ^ 2 + 2x + 5

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

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

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

Ответы [ 6 ]

21 голосов
/ 23 мая 2009

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

Хорошо известное решение (- b + - sqrt (b ^ 2 - 4ac)) / 2a , как известно, не является надежным в вычислениях, когда ac является очень малой конкуренцией до b ^ 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;

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

Для OP измените это для комплексных чисел, как показано на других плакатах.

7 голосов
/ 22 мая 2009

Примерно так будет работать:

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) Выглядел бы еще красивее с наддувом!

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

4 голосов
/ 22 мая 2009

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

3 голосов
/ 22 мая 2009

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

1 голос
/ 22 мая 2009

Обдумывая идею от Блинди:

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)));
  }
}
0 голосов
/ 01 ноября 2012

Я попробовал программу без использования заголовка 'math.h', а также попробовал другую логику ... но моя программа может отвечать только на те квадратные уравнения, у которых коэффициент 'x квадрат' равен единице ..... и где коэффициент «х» может быть выражено как сложение двух чисел, которые являются факторами постоянного члена. например. х квадрат + 8х + 16; х квадрат + 7х + 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();
                 }
...