Pequeño problema al hacer un programa de ecuaciones de segundo grado

Iniciado por DickGumshoe, 7 Noviembre 2011, 15:51 PM

0 Miembros y 1 Visitante están viendo este tema.

DickGumshoe

¡Hola!

Estaba haciendo un programa, el cual me calcula las soluciones de las ecuaciones de segundo grado. Mi código es el siguiente:



Código (cpp) [Seleccionar]

//Este programa calcula la solucion de una ecuacion de segundo grado introduciendo los coeficientes


#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int main (void){
    float a,b,c,x1,x2,x,z;
   
    printf("\n Introduce el primer coeficiente");
    scanf("%f",&a);
   
   
    printf("\n Introduce el segundo coeficiente");
    scanf("%f",&b);
   
   
    printf("\n Introduce el tercer coeficiente");
    scanf("%f",&c);
   
    if(a!=0){
      if(b*b-4*a*c>=0){
        x1=(-b+pow(b*b-4*a*c,0.5))/(2*a);
        x2=(-b-pow(b*b-4*a*c,0.5))/(2*a);
        printf("\n Las dos soluciones son %f y %f", x1,x2);
      }
        else{
          if(b*b-4*a*c<0){
            printf("\n No tiene solucion real");
          }
            else{
              if(b*b-4*a*c==0){
              z=-b/(2*a);                 
              printf("\n La solucion es %f",z);
              }     
            }
           
        }
     }
     
     if(a==0){
       if(b!=0){
         x=(-c)/b;   
         printf("\n La solucion es %f", x);
       }
        else{
          if((b==0)&&(c!=0)){
          printf("\n No tiene solucion");
          }   
            else{
              if((b==0)&&(c==0)){
              printf("\n La solucion es trivial", x);                     
              }
            }         
        }
               
     
     }
     
     printf("\n");
   
   
system ("pause");   
}


Pero ahora quiero que en vez de ponerme "No tiene solución real", me calcule la solución con números complejos... ¿Cómo podría hacerlo? No veo conveniente declarar la "i" como variante, pero si no la pongo, tampoco sale...

Muchísimas gracias.

Ferno

Una solución rápida que se me ocurre es que el radicando de la fórmula de Bahskara sea una variable (b^2 - 4*a*c). Entonces con un condicional, si es negativo, trabajás con el módulo y le agregás la "i" (o el número imaginario que uses) al resultado, sino, trabajás normalmente.
Todo esto partiendo de la base de que la raíz de un número negativo es igual a la raíz de -1 (o sea, "i") por la raíz del módulo del número.
Salú!

DickGumshoe

Muchas gracias.

Lo he puesto así:

Código (cpp) [Seleccionar]
...

if(a!=0){
      if(b*b-4*a*c>=0){
        x1=(-b+pow(b*b-4*a*c,0.5))/(2*a);
        x2=(-b-pow(b*b-4*a*c,0.5))/(2*a);
        printf("\n Las dos soluciones son %f y %f", x1,x2);
      }
        else{
          if(b*b-4*a*c<0){
        x1=(-b+pow(b*b-4*a*c,0.5))/(2*a);
        x2=(-b-pow(b*b-4*a*c,0.5))/(2*a);   
            printf("\n La solucion es %f i y %f i", x1,x2);
          }

...

Pero la solución de, por ejemplo 1x^2 2x 2 me da -1#IND00 i y -1#IND00 i...

Estoy aprendiendo a programar, y todavía no me sale muy bien algunas cosas...

Muchas gracias.


s00rk

Yo hice algo parecido pero en vb6
aqui te lo dejo espero te sirva como ayuda

Código (vb) [Seleccionar]

Dim a As Single, b As Single
        Dim c As Single, d As Single
        Dim x1 As Single, x2 As Single
        a = Val(txta): b = Val(txtb): c = Val(txtc)
        d = b ^ 2 - (4 * a * c) 'dependiendo del valor "d" podemos tener 3 casos, 2 raices reales, 1 raiz real o 2 imaginarias
                                ' si d > 0 tenemos 2 raices reales, si d = 0 tenemos 1 raiz real y si d < 0 tenemos 2 imaginarias
            If d > 0 Then
                x1 = (-b + Sqr(d)) / (2 * a)
                x2 = (-b - Sqr(d)) / (2 * a)
                txtx1 = x1
                txtx2 = x2
            ElseIf d = 0 Then
                x = (-b + Sqr(d)) / (2 * a)
                txtx1 = x
                txtx2 = ""
            Else
                x1 = (Sqr((d * -1))) / (2 * a)
                x2 = (-Sqr((d * -1))) / (2 * a)
                txtx1 = ((-b) / (2 * a)) & " +" & x1 & " i"
                txtx2 = ((-b) / (2 * a)) & " " & x2 & " i"
            End If

тαптяα

Así.

Código (cpp) [Seleccionar]
#include <iostream>
#include <math.h>

using namespace std;

int main()
{
    float a,b,c;
    double x1,x2,y1,y2,z1,z2;
    cout << "Introduce los coeficientes de la ecuacion\nde segundo grado de la forma ax^2 + bx + c\n";
    cout << "\nCoeficiente a: ";
    cin >> a;
    cout << "\nCoeficiente b: ";
    cin >> b;
    cout << "\nCoeficiente c: ";
    cin >> c;
    x1=(b*b)-4*a*c;
    if (x1<0)
    {
        x1=x1*(-1);
        x2=sqrt(x1);
        z1=(-b/(2*a));

        cout << "\nSoluciones imaginarias : " <<z1<<"+"<<x2<<"i y "<<z1<<"-"<<x2<<"i" ;
    }
    else
    {
        x2=sqrt(x1);
        y1=(-b + x2);
        y2=(-b - x2);
        z1=(y1/(2*a));
        z2=(y2/(2*a));
        cout << "\nSoluciones reales: " << z1 << " y " << z2 ;
    }
    return 0;
}

DickGumshoe

#5
Muchísimas gracias a los dos. Gracias a vosotros ya no me sale como resultado lo del -1#IND00, pero  lo que sí me da mal es el resultado final. Por ejemplo de la ecuación x^2 2x 2=0, me da como resultados 0+i y -1-i... Y debería ser 2+i y -2-i... (No lo hago como тαптяαпсє porque no he llegado a la función de los "cout", y prefiero mejorar lo que sé con los if, else, printf, etc., para después dar un paso más.

El código ahora es:

Código (cpp) [Seleccionar]
//Este programa calcula la solucion de una ecuacion de segundo grado introduciendo los coeficientes


#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int main (void){
   float a,b,c,x1,x2,x,z,y1,y2,form=pow(b*b-4*a*c,0.5);

   printf("\n Introduce el primer coeficiente");
   scanf("%f",&a);


   printf("\n Introduce el segundo coeficiente");
   scanf("%f",&b);


   printf("\n Introduce el tercer coeficiente");
   scanf("%f",&c);
   
   y1=(b*b)-4*a*c;

   if(a!=0){
     if(b*b-4*a*c>=0){
       x1=(-b+pow(b*b-4*a*c,0.5))/(2*a);
       x2=(-b-pow(b*b-4*a*c,0.5))/(2*a);
       printf("\n Las dos soluciones son %f y %f", x1,x2);
     }
     
     else{
         if(y1<0){
                         y1=(-b+sqrt(y1*(-1)))/(2*a);
                         y2=(-b-sqrt(y1*(-1)))/(2*a);
                         
   
           printf("\n La solucion es %f+i y %f-i", y1,y2);
         }
     
     
     else{
             if(b*b-4*a*c==0){
             z=-b/(2*a);                
             printf("\n La solucion es %f",z);
             }    
           }

       }
    }

    if(a==0){
      if(b!=0){
        x=(-c)/b;  
        printf("\n La solucion es %f", x);
      }
       else{
         if((b==0)&&(c!=0)){
         printf("\n No tiene solucion");
         }  
           else{
             if((b==0)&&(c==0)){
             printf("\n La solucion es trivial", x);                    
             }
           }        
       }


    }

    printf("\n");


system ("pause");  
}



Muchas gracias.

Ferno

if(b*b-4*a*c>=0) /*Aca podes poner directamente if (y1 >= 0) que es la variable donde calculaste el radicando*/
...
if(y1<0) /*Este if es redundante, con el else anterior, se entiende que y1 es menor a 0*/
...
y1=(-b+sqrt(y1*(-1)))/(2*a);
y2=(-b-sqrt(y1*(-1)))/(2*a); 
/*Procura no mezclar tanto las variables, las soluciones las estas usando en las variables x1 y x2, no está mal, pero tampoco esta muy bien :P*/


Ahora, no está bien el algoritmo a la hora de mostrar el resultado como número imaginario. Porque el número imaginario "i" aparece solo cuando resolvés el radicando, es decir, multiplica solo lo que resuelve la función sqrt (en tu programa, este suma o resta a toda la función real de Bahskara).
Yo separaría en una variable la parte real del resultado Re= (-b/2a) y en otra la parte imaginaria Im = (sqrt((-1)*y1)/2a), y la forma de mostrar el resultado sería:


printf("La primer raiz es %f + (%f)*i \n",Re,Im);
printf("La segunda raiz es %f - (%f)*i \n", Re,Im);


Perdón por no poner tu code entero con comentarios, pero es que no salía bien la previsualización.
Espero que se haya entendido.

тαптяα

Cita de: Ferno en  8 Noviembre 2011, 05:27 AM
if(b*b-4*a*c>=0) /*Aca podes poner directamente if (y1 >= 0) que es la variable donde calculaste el radicando*/
...
if(y1<0) /*Este if es redundante, con el else anterior, se entiende que y1 es menor a 0*/
...
y1=(-b+sqrt(y1*(-1)))/(2*a);
y2=(-b-sqrt(y1*(-1)))/(2*a); 
/*Procura no mezclar tanto las variables, las soluciones las estas usando en las variables x1 y x2, no está mal, pero tampoco esta muy bien :P*/


Ahora, no está bien el algoritmo a la hora de mostrar el resultado como número imaginario. Porque el número imaginario "i" aparece solo cuando resolvés el radicando, es decir, multiplica solo lo que resuelve la función sqrt (en tu programa, este suma o resta a toda la función real de Bahskara).
Yo separaría en una variable la parte real del resultado Re= (-b/2a) y en otra la parte imaginaria Im = (sqrt((-1)*y1)/2a), y la forma de mostrar el resultado sería:


printf("La primer raiz es %f + (%f)*i \n",Re,Im);
printf("La segunda raiz es %f - (%f)*i \n", Re,Im);


Perdón por no poner tu code entero con comentarios, pero es que no salía bien la previsualización.
Espero que se haya entendido.
Yo si que te he entendido, pero si te fijas, mi código lo hace perfectamente.

Saludos.

ghastlyX

Simplemente como comentario, puesto que mucha gente no lo sabe, existe en C++ la librería complex, que permite trabajar con complejos directamente. Pongo un pequeño código que resuelve el problema usándola.
Código (cpp) [Seleccionar]
#include <iostream>
#include <complex>
using namespace std;

const double EPS = 1e-7;

int main() {
    complex<double> a, b, c;
    cin >> a >> b >> c;
    complex<double> x1 = (-b + sqrt(b*b - 4.0*a*c))/(2.0*a), x2 = (-b - sqrt(b*b - 4.0*a*c))/(2.0*a);
    cout << real(x1);
    if (fabs(imag(x1)) > EPS) cout << ((imag(x1) < 0)?"":"+") << imag(x1) << "i" << endl;
    else cout << endl;
    cout << real(x2);
    if (fabs(imag(x2)) > EPS) cout << ((imag(x2) < 0)?"":"+") << imag(x2) << "i" << endl;
    else cout << endl;
}

тαптяα

Cita de: ghastlyX en  8 Noviembre 2011, 20:04 PM
Simplemente como comentario, puesto que mucha gente no lo sabe, existe en C++ la librería complex, que permite trabajar con complejos directamente. Pongo un pequeño código que resuelve el problema usándola.
Código (cpp) [Seleccionar]
#include <iostream>
#include <complex>
using namespace std;

const double EPS = 1e-7;

int main() {
    complex<double> a, b, c;
    cin >> a >> b >> c;
    complex<double> x1 = (-b + sqrt(b*b - 4.0*a*c))/(2.0*a), x2 = (-b - sqrt(b*b - 4.0*a*c))/(2.0*a);
    cout << real(x1);
    if (fabs(imag(x1)) > EPS) cout << ((imag(x1) < 0)?"":"+") << imag(x1) << "i" << endl;
    else cout << endl;
    cout << real(x2);
    if (fabs(imag(x2)) > EPS) cout << ((imag(x2) < 0)?"":"+") << imag(x2) << "i" << endl;
    else cout << endl;
}


Gracias por la información.

Saludos