Raíces de la ecuación cuadrática en C

Más ejercicios resueltos

Si deseas revisar más ejercicios resueltos, haz click en el siguiente botón. 

Hallar las raíces de la ecuación cuadrática es uno de los problemas clásicos que se analizan cuando uno inicia en el mundo de la programación. Si deseas conocer con más detalle la definición de este problema, haz click en el siguiente enlace. En este artículo, analizamos al detalle y paso a paso, el algoritmo para calcular las raíces de una ecuación cuadrática usando como herramienta ANSI C

Parte de esta análisis se encuentra sintetizado en el vídeo «Raíces de la ecuación cuadrática en ANSI C» en nuestro canal de YouTube. Te invitamos a que lo visites.

A continuación presentamos nuestra alternativa de solución al problema del cálculo de las raíces de una ecuación de segundo grado en ANSI C. Analizaremos el algoritmo dividiéndolo en  7 pasos y explicaremos al detalle cada uno de éstos. Los pasos que analizaremos son los siguientes:

  • Lectura de datos.
  • Cálculo del discriminante.
  • Control de flujo para determinar si hay solución real.
  • Control de flujo para calcular la raíz única.
  • Control de flujo para calcular dos raíces reales.
  • Control de flujo para calcular raíces complejas.
  • Validación del coeficiente de la ecuación de segundo grado.

Lectura de datos

Como en todo programa, la primera tarea a realizar, es la lectura de los datos de entrada. ¿Cómo hacemos para leer una ecuación cuadrática? Pues no existe un tipo de dato ecuación, para poder operar la ecuación y hallar su raíces, necesitamos los coeficientes de ésta. Por ello, tendremos que leer cada coeficiente.

La lectura de datos en ANSI C la realizaremos con la función \texttt{scanf}. Recuerde que para poder usar esta función, se debe incluir el archivo de cabecera \texttt{stdio.h} (Standard Input Output). Usaremos las variables \texttt{a}, \texttt{b} y \texttt{c} para almacenar cada uno de los coeficientes leídos de la ecuación.

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

int main() {
    double a, b, c;

    printf("Ingrese coeficientes a, b y c de la ecuación: ");
    scanf("%lf %lf %lf", &a, &b, &c);

    return 0;
} 

Cálculo del discriminante

El programa para resolver la ecuación cuadrática se basa en torno al valor del discriminante. A través de este valor se decidirán las diversas formas de cálculo que existen para esta ecuación: raíz real única, raíces reales diferentes y raíces complejas. Por este motivo, el siguiente paso es calcular el discriminante. El discriminante se define a través de la siguiente expresión b^2-4ac .

Almacenaremos su valor en la variable \texttt{discriminante} y usaremos la expresión \texttt{pow(b,2)-4*a*c} para calcular su valor. Recuerde que en ANSI C, la función \texttt{pow} (disminutivo de power en inglés) permite elevar un número a cualquier potencia. Para poder usar esta función, se debe incluir el archivo de cabecera \texttt{math.h}

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

int main() {
    double a, b, c;

    printf("Ingrese coeficientes a, b y c de la ecuación: ");
    scanf("%lf %lf %lf", &a, &b, &c);

    double discriminante = pow(b, 2) - 4 * a*c;

    return 0;
} 

Control de flujo para determinar si hay solución real

Una vez que se ha calculado el discriminante, procedemos resolver la ecuación cuadrática. Para esto se hace necesario tomar dos caminos diferentes, uno para el cálculo de las raíces reales y otro para las raíces complejas. Para hacer la bifurcación entre estos dos caminos, usamos una estructura algorítmica selectiva con la condición \texttt{discriminante>=0}. Cuando la condición se evalúe con \texttt{1}, calcularemos las raíces reales. Cuando la condición se evalúe con \texttt{0}, procederemos a calcular las raíces complejas.

En ANSI C la selectiva se implementa a través de la instrucción \texttt{if}. Recuerde que la condición se coloca entre paréntesis obligatoriamente.

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

int main() {
    double a, b, c;

    printf("Ingrese coeficientes a, b y c de la ecuación: ");
    scanf("%lf %lf %lf", &a, &b, &c);

    double discriminante = pow(b, 2) - 4 * a*c;
    if (discriminante >= 0){

    } 
    return 0;
} 

Control de flujo para calcular la raíz única

Dentro del camino o alternativa para el cálculo de raíces reales, tenemos dos caminos adicionales: uno para el caso de la raíz única y otro para el caso de las dos raíces diferentes. Vamos a analizar en este paso, la alternativa para la solución única. Según lo indicado en el enunciado, se tendrá una solución única cuando \texttt{discriminante==0}. Recuerde que el operador de comparación de igualdad en ANSI C es \texttt{==}.

Utilizaremos otra selectiva dentro de la selectiva anterior para hacer el cálculo de la raíz única. Esta situación se conoce con el nombre de estructuras algorítmicas selectivas anidadas.  Dado que el \texttt{discriminante} es igual a 0, la raíz se calcula usando la expresión:

x=\cfrac{-b}{2a}.

En la selectiva anidada colocaremos la expresión para calcular la raíz en ANSI C. La expresión usada será \texttt{-b/(2*a)}. Recuerde que los operadores aritméticos de división y multiplicación poseen la misma precedencia y se operan de izquierda a derecha. Por este motivo no es igual \texttt{-b/(2*a)} que \texttt{-b/2*a}. En el caso de \texttt{-b/2*a}, primero se ejecutaría \texttt{-b/2} y luego se multiplicaría por \texttt{a}

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

int main() {
    double a, b, c;

    printf("Ingrese coeficientes a, b y c de la ecuación: ");
    scanf("%lf %lf %lf", &a, &b, &c);

    double discriminante = pow(b, 2) - 4 * a*c;
    if (discriminante >= 0)
        if (discriminante == 0) {
            double x = -b / (2 * a);
            printf("La raíz única es %.3lf\n", x);
        } 
    return 0;
} 

Control de flujo para calcular dos raíces reales

Una vez que terminamos con el flujo para el cálculo de la raíz única, procederemos al cálculo de las raíces reales diferentes. Esto va a ocurrir solamente cuando \texttt{discriminante} \neq \texttt{0} pero a su vez, el discriminante, deberá ser positivo. Por este motivo, este camino lo colocamos dentro del bloque \texttt{else} de la instrucción selectiva que tiene como condición \texttt{discriminante==0}.

 

Según la fórmula general de la ecuación cuadrática descrita en el enunciado, las raíces se calculan de la siguiente manera: 

x_{1,2}=\cfrac{-b \pm \sqrt{b^2-4ac}}{2a}

Debido a esto, la expresión para la calcular la primera raíz es \texttt{(-b+sqrt(discriminante))/(2*a)} y la expresión para la calcular la segunda raíz es \texttt{(-b-sqrt(discriminante))/(2*a)}. Recuerde que en ANSI C, la función \texttt{sqrt} (de las siglas en inglés square root) permite realizar el cálculo de la raíz cuadrada. Esta función también se encuentra declarada en el archivo de cabecera \texttt{math.h}

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

int main() {
    double a, b, c;

    printf("Ingrese coeficientes a, b y c de la ecuación: ");
    scanf("%lf %lf %lf", &a, &b, &c);

    double discriminante = pow(b, 2) - 4 * a*c;
    if (discriminante >= 0)
        if (discriminante == 0) {
            double x = -b / (2 * a);
            printf("La raíz única es %.3lf\n", x);
        } else {
            double x1, x2;
            x1 = (-b + sqrt(discriminante)) / (2 * a);
            x2 = (-b - sqrt(discriminante)) / (2 * a);
            printf("La raíz real x1 es %.3lf\n", x1);
            printf("La raíz real x2 es %.3lf\n", x2);
        } 
    return 0;
} 

Control de flujo para calcular raíces complejas

Finalmente diseñamos el flujo para que se calculen las raíces complejas. Solo haremos esto cuando  \texttt{discriminante<0}. Por este motivo, este camino lo colocamos dentro del bloque \texttt{else} de la estructura algorítmica selectiva que tiene como condición \texttt{discriminante>=0}.

Dado que el \texttt{discriminante} es negativo, lo actualizamos con el valor absoluto para poder obtener la raíz cuadrada de éste. Para obtener la solución compleja, realizaremos el cálculo de la parte real y la parte imaginaria por separado. Luego, al imprimir, escribimos ambas partes y le incrementamos el caracter \texttt{i} para simular el número real.

Recuerde que en ANSI C, la función \texttt{fabs} permite obtener el valor absoluto de un número real. Esta función se encuentra declarada en el archivo de cabecera \texttt{math.h}.

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

int main() {
    double a, b, c;

    printf("Ingrese coeficientes a, b y c de la ecuación: ");
    scanf("%lf %lf %lf", &a, &b, &c);

    double discriminante = pow(b, 2) - 4 * a*c;
    if (discriminante >= 0)
        if (discriminante == 0) {
            double x = -b / (2 * a);
            printf("La raíz única es %.3lf\n", x);
        } else {
            double x1, x2;
            x1 = (-b + sqrt(discriminante)) / (2 * a);
            x2 = (-b - sqrt(discriminante)) / (2 * a);
            printf("La raíz real x1 es %.3lf\n", x1);
            printf("La raíz real x2 es %.3lf\n", x2);
        } 
    else {
        double parteReal, parteImaginaria;
        discriminante = fabs(discriminante);
        parteReal = -b / (2 * a);
        parteImaginaria = sqrt(discriminante) / (2 * a);
        printf("La raíz compleja x1 es %.3lf + %.3lfi\n", parteReal, parteImaginaria);
        printf("La raíz compleja x2 es %.3lf - %.3lfi\n", parteReal, parteImaginaria);
    }
    return 0;
} 

Validación del coeficiente de la ecuación

Para terminar el algoritmo, procedemos a la validación del coeficiente \texttt{a}. Para que exista una ecuación cuadrática, existe una restricción: el coeficiente \texttt{a} debe ser diferente de cero. Esta validación la realizaremos inmediatamente después de la lectura de los datos de entrada. 

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

int main() {
    double a, b, c;

    printf("Ingrese coeficientes a, b y c de la ecuación: ");
    scanf("%lf %lf %lf", &a, &b, &c);

    if (a == 0)
        printf("El coeficiente a no puede ser igual a cero");
    else {
        double discriminante = pow(b, 2) - 4 * a*c;
        if (discriminante >= 0)
            if (discriminante == 0) {
                double x = -b / (2 * a);
                printf("La raíz única es %.3lf\n", x);
            } else {
                double x1, x2;
                x1 = (-b + sqrt(discriminante)) / (2 * a);
                x2 = (-b - sqrt(discriminante)) / (2 * a);
                printf("La raíz real x1 es %.3lf\n", x1);
                printf("La raíz real x2 es %.3lf\n", x2);
            }
        else {
            double parteReal, parteImaginaria;
            discriminante = fabs(discriminante);
            parteReal = -b / (2 * a);
            parteImaginaria = sqrt(discriminante) / (2 * a);
            printf("La raíz compleja x1 es %.3lf + %.3lfi\n", parteReal, parteImaginaria);
            printf("La raíz compleja x2 es %.3lf - %.3lfi\n", parteReal, parteImaginaria);
        }
    }
    return 0;
} 

Conclusión​​

Hemos presentado en este artículo, una alternativa de solución al algoritmo para calcular las raíces de una ecuación cuadrática en ANSI C. Se ha utilizado para el control de flujo, estructuras selectivas anidadas. Podrá descargar la solución propuesta en el repositorio GitHub de iterando++ a través del siguiente enlace

Hemos preparado otros artículos adicionales en donde describimos al detalle la implementación de este problema PSeInt y en otros lenguajes de programación. Te invitamos a leer los siguientes artículos de iterando++

Si quieres profundizar en el lenguaje ANSI C, no hay mejor libro que C Programming Language de Brian Kernighan  y Dennis Ritchie. Es un libro clásico escrito por el creador del lenguaje C. Uno de los libros favoritos de los que inician en ANSI C es  C Programming Absolute Beginner’s Guide de Greg Perry y Dean Miller.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *