Ecuación de segundo grado [Complejos]

Iniciado por programator11, 6 Agosto 2014, 13:20 PM

0 Miembros y 2 Visitantes están viendo este tema.

programator11

Hola a todos.

Veréis estoy empezando a trabajar con números complejos y a emplear en general las funciones de math.h y complex.h, y para practicar me pareció una buena idea ,por ejemplo, realizar un programa que resolviera ecuaciones de 2ºgrado.

Mi codigo es el siguiente;

#include<stdio.h>
#include<complex.h>
#include<math.h>
void grado (float,float,float);
main()
  {
  float a,b,c;
  printf ("Introduzca los coeficientes de la ecuacion en el formato (a,b,c)\n\n");
  scanf ("%f,%f,%f",&a,&b,&c);
  grado (a,b,c);
  return 0;
  }

void grado (float a,float b,float c)
  {
  if (a==0)
    {
    printf ("No se puede dividir por a=0");
    }
  else
    {
      float res1,res2;
      res1 = (-b+(sqrt(pow(b,2)-4*a*c)))/(2*a);
      res2 = (-b-(sqrt(pow(b,2)-4*a*c)))/(2*a);
     
      if (pow(b,2)-4*a*c<0)
        {
          double _Complex resimag1 = res1;
    double _Complex resimag2 = res2;
    printf ("\nEl primer resultado es %f \n El segundo resultado es %f \n",resimag1,resimag2);
        }
      else
        {
        printf ("\nEl primer resultado es %f \n El segundo resultado es %f \n",res1,res2);
        }
    }
return;
  }
     

        
Para resultados comunes no experimento ningún problema, pero cuando los coeficientes me dan un numero complejo, el resultado invariablemente me da 0.00000.

Seguramente no sean correctas las funciones implementadas dentro del;

if (pow(b,2)-4*a*c<0) \\Numeros complejos
        {
          double _Complex resimag1 = res1;
    double _Complex resimag2 = res2;
    printf ("\nEl primer resultado es %f \n El segundo resultado es %f \n",resimag1,resimag2);


¿Me podeis echar una mano?

Muchas gracias. :)

eferion

Estás calculando el resultado de la ecuación usando las funciones de math.h... que no tienen soporte para números complejos

Código (cpp) [Seleccionar]
double _Complex resimag1 = res1;

res1 es un double normalito... no entiende de imaginarios ni sabe siquiera que existen.

programator11

Cita de: eferion en  6 Agosto 2014, 14:39 PM
Estás calculando el resultado de la ecuación usando las funciones de math.h... que no tienen soporte para números complejos

Código (cpp) [Seleccionar]
double _Complex resimag1 = res1;

res1 es un double normalito... no entiende de imaginarios ni sabe siquiera que existen.

Entiendo...tendria que implementar entonces otra libreria para ello?

Muchas gracias por tu tiempo ;)

eferion

No necesariamente... tienes que separar los diferentes elementos de la ecuación... por un lado la parte real y por otro la "posible" imaginaria. Es decir, si tenemos que las dos raices son:

y1 = -b/2a + sqrt(b^2-4ac)/2a
y2 = -b/2a - sqrt(b^2-4ac)/2a

Hacemos la separación:

r = -b/2a
i = sqrt(b^2-4ac)/2a

De tal forma que:

y1 = r + i
y2 = r - i

Ahora ya tenemos que R siempre es real, mientras que I será real sólo si el interior de la raiz cuadrada no es negativo. Es decir, podríamos tener algo del tipo:

x = b^2-4ac
r = -b/2a
i = sqrt(x)

entonces, si x >= 0 podemos calcular las dos raices de la forma acostumbrada... pero si x < 0, entonces tenemos número imaginario... dado que ya tienes separada la parte imaginaria es facil conformar el número complejo:


double _Complex resimag1 = r + i * I;
double _Complex resimag2 = r - i * I;


Xandrete

Cita de: programator11 en  6 Agosto 2014, 15:01 PM
Entiendo...tendria que implementar entonces otra libreria para ello?

Muchas gracias por tu tiempo ;)

No, no, no tienes que implementar ninguna librería nueva (aunque podrías implementar las funciones necesarias para operar con complejos, sería un buen ejercicio). No hace falta que incluyas la biblioteca math. La complex ya te viene con las funciones sqrt y pow preparadas para operar con complejos. Quita el include de math.h, que no te hace falta. Y haz que res1 y res2 sean objetos de la clase complex<double>, en lugar de float. http://www.cplusplus.com/reference/complex/

Podrías, ya que estás, completar el programa para que el usuario pueda introducir coeficientes que no sean necesariamente reales, sino complejos también.

Cita de: eferion en  6 Agosto 2014, 15:19 PM
No necesariamente... tienes que separar los diferentes elementos de la ecuación... por un lado la parte real y por otro la "posible" imaginaria. Es decir, si tenemos que las dos raices son:

y1 = -b/2a + sqrt(b^2-4ac)/2a
y2 = -b/2a - sqrt(b^2-4ac)/2a

Hacemos la separación:

r = -b/2a
i = sqrt(b^2-4ac)/2a

De tal forma que:

y1 = r + i
y2 = r - i

Ahora ya tenemos que R siempre es real, mientras que I será real sólo si el interior de la raiz cuadrada no es negativo. Es decir, podríamos tener algo del tipo:

x = b^2-4ac
r = -b/2a
i = sqrt(x)

entonces, si x >= 0 podemos calcular las dos raices de la forma acostumbrada... pero si x < 0, entonces tenemos número imaginario... dado que ya tienes separada la parte imaginaria es facil conformar el número complejo:


double _Complex resimag1 = r + i * I;
double _Complex resimag2 = r - i * I;



Correcto, pero originalmente programator11 quería hacerlo utilizando la clase complex, que ya tiene preparadas funciones para no tener que preocuparse de separar la parte imaginaria de la real. Con la clase complex, puedes hacer la raiz cuadrada de un número negativo o complejo tranquilamente, sin realizar tú las comprobaciones.

eferion

Cita de: Xandrete en  6 Agosto 2014, 15:29 PM
Correcto, pero originalmente programator11 quería hacerlo utilizando la clase complex, que ya tiene preparadas funciones para no tener que preocuparse de separar la parte imaginaria de la real. Con la clase complex, puedes hacer la raiz cuadrada de un número negativo o complejo tranquilamente, sin realizar tú las comprobaciones.

Como bien comentó nuestro compañero programator11, está practicando. Si le doy la solución definitiva... ¿qué va a practicar?

Xandrete

Cita de: eferion en  6 Agosto 2014, 15:53 PM
Como bien comentó nuestro compañero programator11, está practicando. Si le doy la solución definitiva... ¿qué va a practicar?

¿?

Ya, pero tenía el código casi completo para usar la clase complex, sólo tiene que borrar una línea y cambiar el tipo de dos variables. Yo proponía una solución a su problema siguiendo el camino que ya había comenzado. También le he sugerido implementar las operaciones básicas entre complejos, como ejercicio. Estoy seguro de que programator11 valorará y tendrá en consideración tu respuesta.

Saludos.