2009-05-22 24 views
6

Estoy tratando de escribir una función en C++ que resuelva para X usando la ecuación cuadrática. Esto es lo que he escrito en un principio, que parece funcionar, siempre y cuando no hay números complejos para una respuesta:Resuelva la ecuación cuadrática en 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; 

Si, por ejemplo, yo uso la ecuación: x^2 - x - 6, I obtener la solución 3, -2 correctamente.

Mi pregunta es ¿cómo tener en cuenta que para los números complejos .... por ejemplo, dada la ecuación:

x^2 + 2x + 5

Resolución de la mano, que obtendría -1 + 2i, -1 - 2i.

Bueno, supongo que dos preguntas, ¿puedo escribir lo anterior mejor y también hacer que tenga en cuenta el número complejo?

¡Gracias por cualquier ayuda!

+3

Los otros chicos siempre buenas respuestas para ninguna razón para mí para tratar de eclipsar a ellos;) Sin embargo, si desea una solución más general a la ecuación ax^2 + bx + c = 0, recuerde que a = = 0 debe ser un valor válido. Esto daría como resultado una división de cero, por lo que debe encargarse de este caso por separado. En este caso, significa que te queda una ecuación lineal con una raíz. ¡Salud! – ralphtheninja

+0

Usted implica que le preocupan las raíces complejas, pero ¿qué pasa con los coeficientes complejos en la ecuación original? –

+1

Los coeficientes complejos requieren otro enfoque por completo. Así que esa será la siguiente pregunta :) * desciende y prepara una respuesta antes de la mano * – ralphtheninja

Respuesta

8

Algo como esto funcionaría:

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; 
} 

De esta manera se obtiene los resultados de una manera similar para ambos resultados reales y complejos (los resultados reales sólo tienen el conjunto de parte imaginaria a 0). ¡Se vería aún más bonito con impulso!

corregir: se corrigió por el delta y se agregó un cheque para casos degenerados como a = 0. ¡Noche sin dormir ftl!

+0

Si el sqrt tiene éxito, el resultado es> = 0. Y si el argumento es negativo, su programa se bloquea. Primero debe probar el letrero y luego calcular el sqrt. Si el signo fuera negativo, establecería result.first.i = + sqrt (4 * a * c-b * b)/2/a. (¿Por qué definir su propio tipo si hay un fine std :: pair MSalters

+0

debe ser delta = b * b-4 * a * c, y tomar sqrt solo cuando delta> = 0. delta = 0 o a = 0 son casos válidos cuando tenemos una raíz. ¿Qué pasa si a = b = 0 yc = 1? –

+0

¿Qué pasa si? Esa no es una función cuadrática, y la parte/2/a fallará. Esto funciona razonablemente bien si delta = 0, excepto que devolverá el mismo resultado dos veces. – MSalters

4

Lo tiene más o menos, simplemente verifique si la parte que está dentro de la raíz cuadrada es negativa y luego realice un seguimiento de eso por separado en sus reducciones.

3

Como nota al pie: Al dividir, siempre verifique si el denominador no es cero. Y recordar los números de punto flotante a usar algo como:

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

Se podría básicamente sólo tiene que utilizar en lugar de std::complex<float>float obtener apoyo para los números complejos.

1

mellar la idea de 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

Una nota importante a todo esto. Las soluciones que se muestran en estas respuestas y en la pregunta original no son sólidas.

El conocido solución (-b + - sqrt (b^2 - 4ac))/2a se sabe que es no robusto en el cálculo cuando ac es muy pequeña competían para b^2, porque uno está restando dos valores muy similares. Es mejor utilizar la solución menos conocida 2c/(-b - + sqrt (b^2 -4ac)) para la otra raíz.

una solución sólida se puede calcular como:

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

El uso de señal (b) asegura que no estamos restar dos valores similares.

Para el OP, modifique esto para números complejos como se muestra en otros carteles.

+1

+1 esto es significativamente más robusto que '(-b +/- sqrt (b * b - 4 * a * c))/(2a)'. Por cierto: dado que 'temp' podría ser 0.0, se necesita la verificación previa a la división. (por ejemplo, a, b, c = 1,0,0). – chux

+0

'temp' solo puede ser 0 si' b' es 0 –

-1

Probé el programa sin usar el encabezado 'math.h' y también intenté una lógica diferente ... pero mi programa puede responder solo aquellas ecuaciones cuadráticas que tienen coeficiente de 'x cuadrado' como uno ..... y donde el coeficiente de 'x' se puede expresar como una suma de dos números que son factores de término constante. por ej. x cuadrado + 8x + 16; x cuadrado + 7x + 12; etc. aquí 8 = 4 + 4 & 16 = 4 * 4; aquí el coeficiente de x se puede expresar como una suma de dos números que son factores del término constante 16 ... Yo mismo no estoy completamente satisfecho con él, pero intenté con algo diferente, sin usar la fórmula para resolver la ecuación cuadrática. código es;

 #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(); 
       } 
Cuestiones relacionadas