Algoritmo da Equação do Terceiro Grau

Por
|  

Introdução

Algoritmo da Equação do Terceiro Grau

Assim como a equação do segundo grau, a equação do terceiro grau possui uma fórmula para extração das raízes a partir de seus coeficientes. Entretanto, a fórmula em questão, conhecida como fórmula de Tartaglia-Cardano ou apenas fórmula de Cardano, não é tão simples quanto a fórmula de Bhaskara.

Evidentemente, a implementação da fórmula de Tartaglia-Cardano numa linguagem de programação também não é tão trivial. Pensando nisso, este artigo foi escrito com o intuito de apresentar algumas implementações da fórmula em diferentes linguagens.

O texto inicia com uma breve síntese de como a fórmula funciona e, em seguida, os códigos são apresentados. Caso o leitor queira se aprofundar, também há um conteúdo extra sobre como a fórmula é deduzida e referências sobre o assunto.

Tenha em mente que o objetivo do artigo não é ensinar como resolver equações do terceiro grau, mas apresentar um algoritmo que computa as raízes de uma a partir de seus coeficientes.

Veja também: Calculadora de Equações do Terceiro Grau

A Fórmula de Tartaglia-Cardano

Uma equação do terceiro grau é uma equação com a seguinte forma

$$ax^3+bx^2+cx+d=0,\quad a\neq 0.$$

Para os propósitos da postagem, os coeficientes serão considerados reais.

Se dividirmos a equação pelo primeiro coeficiente, obtemos uma equação da forma

$$x^3+Ax^2+Bx+C=0.$$

Fazendo a mudança de variável $x = y - \cfrac{A}{3}$ e realizando algumas manipulações algébricas, obtemos uma equação da seguinte forma [2]

$$y^3+py+q = 0.$$

As constantes $p$ e $q$ dependem dos coeficientes:

$$\begin{align*}p = B - \frac{A^2}{3}\\q = C +\frac{2A^3}{27} -\frac{AB}{3}.\end{align*}$$

O discriminante da equação em $y$ é dado por

$$\Delta = \frac{q^2}{4}+\frac{p^3}{27}.$$

O valor do discriminante irá determinar os tipos de raízes que obteremos [2]

  • Se $\Delta = 0$, a equação terá três raízes reais e uma delas será repetida;
  • Se $\Delta < 0$, a equação terá três raízes reais distintas;
  • Se $\Delta > 0$, a equação terá uma raiz real e duas raízes complexas conjugadas.

A primeira raiz da equação em $y$ é dada pela fórmula

$$y_1=\sqrt[3]{-\frac{q}{2}+\sqrt{\Delta}} + \sqrt[3]{-\frac{q}{2}-\sqrt{\Delta}}.$$

Quando $\Delta\geq 0$, é possível calcular $y_1$ sem a necessidade de recorrer à teoria dos números complexos. As demais raízes, neste caso, serão dadas por

$$\begin{align*}y_{2,3} = \frac{-y_1\pm\sqrt{\Delta_2}}{2}\\\Delta_2 = -\left(3y_1^2+4p\right),\end{align*}$$

que é basicamente a fórmula de Bhaskara. Observe que devemos dar uma atenção especial ao caso $\Delta_2 < 0$, pois é ele que irá produzir as raízes complexas conjugadas.

Quando $\Delta < 0$, $y_1$ será a soma de dois números complexos conjugados. Na prática, o cálculo das raízes requer o uso da fórmula de Euler ou da fórmula de De Moivre e elas são expressas da seguinte forma:

$$\begin{align*}y_1 = 2\sqrt[3]{\rho}\cos\left(\frac{\theta}{3}\right)\\y_2 = 2\sqrt[3]{\rho}\cos\left(\frac{\theta + 2\pi}{3}\right)\\y_3 = 2\sqrt[3]{\rho}\cos\left(\frac{\theta + 4\pi}{3}\right),\end{align*}$$

onde,

$$\begin{align*}\rho = \sqrt{\frac{q^2}{4}+\left|\Delta\right|}\\\theta = \arccos\left(-\frac{q}{2\rho}\right).\end{align*}$$

Independente do caso, após calcular os três valores de $y$, basta subtrair $A/3$ para obter os respectivos valores de $x$, que é o que queremos.

Códigos

A implementação da fórmula de Tartaglia-Cardano em uma linguagem de programação está sujeita a erros de arredondamento devido à representação dos números em ponto flutuante. Portanto, as raízes provavelmente apresentarão erros, mas serão muito próximas das raízes exatas.

Isso ocorre porque as operações envolvidas nos cálculos, tais como divisões, raízes cúbicas e quadradas e funções trigonométricas, produzem números decimais infinitos (racionais e irracionais) que não podem ser representados de maneira exata num computador.

Java

Código em Java implementando a fórmula:

/*
 * Código por Henrique Felipe (GitHub: HenriqueIni)
 * https://www.blogcyberini.com/
 * Código sob licença MIT.
 */
public class TartagliaCardanoFormula {
    //Resolve uma equação do terceiro grau utilizado a fórmula de Tartaglia-Cardano
    //Os coeficientes são números reais e o primeiro coeficiente não pode ser zero

    public static String[] solveEquation(double a, double b, double c, double d) {
        if (a == 0) {
            throw new IllegalArgumentException("a == 0: the first coefficient can't be equal to zero.");
        }
        String[] roots = new String[3];
        //converte a equação para forma x^3+Ax^2+Bx+C=0
        double A = b / a;
        double B = c / a;
        double C = d / a;

        //constantes da conversão para y^3+py+q=0
        double p = B - A * A / 3.0;
        double q = C + 2 * A * A * A / 27.0 - A * B / 3.0;

        //discriminante
        double delta = q * q / 4.0 + p * p * p / 27.0;

        if (delta >= 0) {
            //primeira raiz
            double y1 = Math.cbrt(-q / 2.0 + Math.sqrt(delta)) + Math.cbrt(-q / 2.0 - Math.sqrt(delta));
            roots[0] = String.valueOf(y1 - A / 3.0);
            //discriminante secundário de uma equação do segundo grau
            double delta2 = -3.0 * y1 * y1 - 4.0 * p;
            if (delta2 >= 0) {
                roots[1] = String.valueOf((-y1 + Math.sqrt(delta2)) / 2.0 - A / 3.0);
                roots[2] = String.valueOf((-y1 - Math.sqrt(delta2)) / 2.0 - A / 3.0);
            } else {
                //raízes complexas
                double realPart = -y1 / 2.0;
                double imPart = Math.sqrt(Math.abs(delta2)) / 2.0;
                roots[1] = formatComplexResult(realPart - A / 3.0, imPart);
                roots[2] = formatComplexResult(realPart - A / 3.0, -imPart);
            }
        } else {
            //utiliza a fórmula de Euler para calcular as raízes
            double rho = Math.sqrt(q * q / 4.0 + Math.abs(delta));
            double theta = Math.acos(-q / (2.0 * rho));
            roots[0] = String.valueOf(2.0 * Math.cbrt(rho) * Math.cos(theta / 3.0) - A / 3.0);
            roots[1] = String.valueOf(2.0 * Math.cbrt(rho) * Math.cos((theta + 2.0 * Math.PI) / 3.0) - A / 3.0);
            roots[2] = String.valueOf(2.0 * Math.cbrt(rho) * Math.cos((theta + 4.0 * Math.PI) / 3.0) - A / 3.0);
        }
        return roots;
    }
    //Formata um número complexo (Forma a+bi).

    private static String formatComplexResult(double realPart, double imPart) {
        if (realPart == 0 && imPart == 0) {
            return "0";
        }
        String number = "";
        if (realPart != 0) {
            number += realPart;
            if (imPart > 0) {
                number += "+" + imPart + "i";
            } else if (imPart < 0) {
                number += imPart + "i";
            }
        } else {
            number += imPart + "i";
        }
        return number;
    }
}

JavaScript

Código em JavaScript implementando a fórmula:

/*
 * Código por Henrique Felipe (GitHub: HenriqueIni)
 * https://www.blogcyberini.com/
 * Código sob licença MIT.
 */
/*
 * Resolve uma equação do terceiro grau utilizado a fórmula de Tartaglia-Cardano
 * Os coeficientes são números reais e o primeiro coeficiente não pode ser zero
 * As raízes complexas são formatadas utilizando o formato a+bi
 * Forma da equação: ax^3+bx^2+cx+d = 0
 */
function solve(a, b, c, d) {
    if (a == 0) {
        throw "the coefficient a can't be zero!";
    }
    //o container das raízes (elas serão Strings)
    var roots = [];
    //converte a equação para forma x^3+Ax^2+Bx+C=0
    var A = b / a;
    var B = c / a;
    var C = d / a;

    //constantes da conversão para y^3+py+q=0
    var p = B - A * A / 3;
    var q = C + 2 * A * A * A / 27 - A * B / 3;

    //discriminante
    var delta = q * q / 4 + p * p * p / 27;
    
    if (delta >= 0) {
        //primeira raiz
        var y1 = Math.cbrt(-q / 2 + Math.sqrt(delta)) + Math.cbrt(-q / 2 - Math.sqrt(delta));
        roots[0] = (y1 - A / 3).toString();
        //discriminante secundário de uma equação do segundo grau
        var delta2 = -3 * y1 * y1 - 4 * p;
        if (delta2 >= 0) {
            roots[1] = ((-y1 + Math.sqrt(delta2)) / 2 - A / 3).toString();
            roots[2] = ((-y1 - Math.sqrt(delta2)) / 2 - A / 3).toString();
        } else {
            //raízes complexas
            var realPart = -y1 / 2;
            var imPart = Math.sqrt(Math.abs(delta2)) / 2;
            roots[1] = formatComplexResult(realPart - A / 3, imPart);
            roots[2] = formatComplexResult(realPart - A / 3, -imPart);
        }
    } else {
        //utiliza a fórmula de Euler para calcular as raízes
        var rho = Math.sqrt(q * q / 4 + Math.abs(delta));
        var theta = Math.acos(-q / (2 * rho));
        roots[0] = (2 * Math.cbrt(rho) * Math.cos(theta / 3) - A / 3).toString();
        roots[1] = (2 * Math.cbrt(rho) * Math.cos((theta + 2 * Math.PI) / 3) - A / 3).toString();
        roots[2] = (2 * Math.cbrt(rho) * Math.cos((theta + 4 * Math.PI) / 3) - A / 3).toString();
    }
    return roots;
}

//Formata um número complexo (Forma a+bi).
function formatComplexResult(realPart, imPart) {
    //um caso simples
    if (realPart == 0 && imPart == 0) return "0";
        var number = "";
        if (realPart != 0) {
            number += realPart;
        if (imPart > 0) {
            number += "+" + imPart + "i";
        } else if (imPart < 0) {
            number += imPart + "i";
        }
    } else {
        number += imPart + "i";
    }
    return number;
}

Download dos Códigos

Os códigos apresentados aqui estão disponíveis no Google Drive e no GitHub.

Leitura Opcional: Deduzindo a Fórmula de Tartaglia-Cardano

Caso o leitor tenha interesse em saber como deduzir a fórmula de Tartaglia-Cardano, então sugiro que o mesmo leia esta seção e as referências no final do artigo. O texto que segue é baseado principalmente nas referências [1] e [2].

Seja a equação do terceiro grau

$$ax^3+bx^2+cx+d=0,\quad a\neq 0,$$

onde $a$, $b$, $c$ e $d$ são reais. Dividimos a equação por $a$ para obter a seguinte equação

$$x^3+\frac{b}{a}x^2+\frac{c}{a}x+\frac{d}{a} = 0,$$

ou ainda,

$$x^3+Ax^2+Bx+C = 0,$$

onde $A = \cfrac{b}{a}$, $B = \cfrac{c}{a}$ e $C = \cfrac{d}{a}$.

Fazendo a substituição $x = y - \cfrac{A}{3}$, obtemos

$$\left(y-\frac{A}{3}\right)^3+A\left(y-\frac{A}{3}\right)^2+B\left(y-\frac{A}{3}\right)+C=0$$

que é igual a

$$y^3+\left(B-\frac{A^2}{3}\right)y+C+\frac{2A^3}{27}-\frac{AB}{3}=0.$$

É conveniente definir as constantes

$$p = B-\frac{A^2}{3}\quad q=C+\frac{2A^3}{27}-\frac{AB}{3}$$

Com isso, a equação terá a seguinte forma

$$y^3+py+q=0.$$

Um fato notável nesta última equação é a ausência do termo de segundo grau.

Continuando, vamos supor que a solução possa ser expressa como a soma de dois termos

$$y = u + v.$$

Substituindo na equação, temos

$$(u+v)^3+p(u+v)+q=0.$$

Após algumas manipulação algébricas, obteremos

$$u^3+v^3+(3uv+p)(u+v) + q = 0.$$

Vamos assumir que $q = -(u^3+v^3)$ e que $p = -3uv$. Dessa forma, teremos a identidade $0 = 0$. É claro, isso não resolve o problema, pois $u$ e $v$ ainda são desconhecidos. Por outro lado, perceba que

$$\begin{align*}u^3+v^3=-q\\u^3v^3=-\frac{p^3}{27}.\end{align*}$$

Isto é, podemos calcular $u^3$ e $v^3$ através de uma equação do segundo grau. Isso é possível porque se $z_1$ e $z_2$ são raízes de uma equação do segundo grau, então a equação pode ser expressa em termos de $z_1$ e $z_2$:

$$z^2-(z_1+z_2)z+z_1z_2=0.$$

No nosso caso, $z_1 = u^3$ e $z_2=v^3$. Logo,

$$z^2+qz-\frac{p^3}{27} = 0.$$

Portanto,

$$\begin{align*}u^3=-\frac{q}{2}+\sqrt{\frac{q^2}{4}+\frac{p^3}{27}}\\v^3=-\frac{q}{2}-\sqrt{\frac{q^2}{4}+\frac{p^3}{27}}.\end{align*}$$

Logo, podemos calcular a primeira raiz da equação:

$$y_1=u+v=\sqrt[3]{-\frac{q}{2}+\sqrt{\Delta}}+\sqrt[3]{-\frac{q}{2}-\sqrt{\Delta}}$$

onde,

$$\Delta = \frac{q^2}{4}+\frac{p^3}{27}.$$

A constante $\Delta$ é o discriminante da equação. Independente do seu valor, $y_1$ será sempre real. Entretanto, observe que o caso $\Delta \geq 0$ é mais fácil de calcular, pois, a princípio, não precisamos fazer cálculos com números complexos.

Para obter as demais raízes, devemos lembrar que uma equação do terceiro grau pode ser fatorada da seguinte forma

$$(y-y_1)(y-y_2)(y-y_3)=0.$$

Como já conhecemos $y_1$, então basta dividir a equação original por $y-y_1$.

$$\begin{align*}\frac{y^3+py+q}{y-y_1} = y^2+y_1y+(p+y_1^2)\\\text{Resto: }y_1^3+py_1+q.\end{align*}$$

Logo, as demais raízes da equação são obtidas resolvendo a equação do segundo grau

$$y^2+y_1y+(p+y_1^2) = 0.$$

Observe que o resto da divisão é basicamente o polinômio $p(y)=y^3+py+q$ com $y=y_1$. Mas como $y_1$ é um dos zeros de $p(y)$, então o resto da divisão será zero e, portanto, a divisão é exata.

Resolvendo a equação do segundo grau obtida, temos

$$\begin{align*}\Delta_2=-(3y_1^2+4p)\\y_{2,3}=\frac{-y_1\pm\sqrt{\Delta_2}}{2}.\end{align*}$$

Quando $\Delta = 0$, então $\Delta_2 = 0$ e as raízes serão

$$\begin{align*}y_1 = -\sqrt[3]{4q}\\y_2 = y_3 = \sqrt[3]{\frac{q}{2}}.\end{align*}$$

Quando $\Delta > 0$, então $\Delta_2 < 0$ e as raízes $y_2$ e $y_3$ serão complexas conjugadas.

Para $\Delta < 0$, faremos uma abordagem um pouco diferente, pois precisaremos lidar com números complexos nos cálculos.

Anteriormente, eu afirmei que $y_1$ seria sempre real. Isso é óbvio para $\Delta \geq 0$. Por outro lado, para $\Delta < 0$ teremos a soma de dois números complexos. Pior ainda: como a raiz cúbica de um número complexo tem três resultados possíveis, então, a primeira vista, teríamos nove soluções [1]. Felizmente, isso não é verdade.

Primeiro, observe que os radicandos são complexos conjugados:

$$y_1=\sqrt[3]{-\frac{q}{2}+i\sqrt{\left|\Delta\right|}}+\sqrt[3]{-\frac{q}{2}-i\sqrt{\left|\Delta\right|}}$$

Nota: não precisamos tomar $\sqrt{\Delta} = \pm i\sqrt{\left|\Delta\right|}$, pois isso já foi feito quando resolvemos a equação em $z$.

Além disso, se $R_{\text{cub}}=\{R_1,R_2,R_3\}$ é o conjunto das raízes cúbicas de um número complexo $W$, então o conjunto das raízes cúbicas de $\overline{W}$ será $R_{\text{conj}} = \{\overline{R_1},\overline{R_2},\overline{R_3}\}$.

A afirmação acima parece estar fora de contexto, porém é importante saber que a soma de um número complexo com o seu conjugado é um número real (o dobro da parte real deles):

$$(a+bi) + (a-bi) = 2a.$$

É justamente por causa desta propriedade que $y_1$ é real. Entretanto, surge outro problema: você poderia somar raízes cúbicas que não são conjugadas e, dessa forma, $y_1$ não seria real. Além disso, ainda temos os problema das nove soluções.

Para resolver isso, devemos lembrar que $p=-3uv$ e que $p$ é real. Portanto, o produto $uv$ tem que ser real. Na prática, ao escolher o valor de $u$, o valor de $v$ será o complexo conjugado de $u$, pois o produto de um número complexo pelo eu conjugado é real. Ou seja, para cada $u$ haverá apenas uma possibilidade para o valor de $v$. Logo, teremos apenas três raízes, que serão reais.

Continuando os cálculos, observe que apesar de termos utilizado a fórmula $y_1=u+v$ apenas para o cálculo da primeira raiz, ela também é válida para as demais raízes: $y = u + v$.

Como $v = \overline{u}$, então

$$y = u + v = u + \overline{u} = 2\operatorname{Re}(u).$$

A expressão $\operatorname{Re}(u)$ significa "a parte real de $u$". Vamos tomar $u = \sqrt[3]{W}$ e colocar $W$ na forma polar ($W$ é o radicando):

$$W = -\frac{q}{2}+i\sqrt{\left|\Delta\right|} =\rho e^{i\theta} = \rho(\cos\theta+i\operatorname{sen}\theta).$$

Os valores de $\rho$ e $\theta$ são dados por

$$\begin{align*}\rho =\sqrt{\frac{q^2}{4}+\left|\Delta\right|}\\\theta=\arccos\left(\frac{-\frac{q}{2}}{\rho}\right) = \arccos\left(-\frac{q}{2\rho}\right).\end{align*}$$

Aplicando a fórmula de De Moivre para calcular a raiz cúbica, temos

$$u=\sqrt[3]{W} = \sqrt[3]{\rho}\left[\cos\left(\frac{\theta+2\pi n}{3}\right)+i\operatorname{sen}\left(\frac{\theta+2\pi n}{3}\right)\right],$$

onde $n = 0,1,2$. Como $y=2\operatorname{Re}(u)$, então temos

$$y = 2\sqrt[3]{\rho}\cos\left(\frac{\theta+2\pi n}{3}\right),\quad n = 0,1,2.$$

Ou seja, calculamos o dobro da parte real de $u$. Explicitamente, as raízes são

$$\begin{align*}y_1 = 2\sqrt[3]{\rho}\cos\left(\frac{\theta}{3}\right)\\y_2 = 2\sqrt[3]{\rho}\cos\left(\frac{\theta+2\pi}{3}\right)\\y_3 = 2\sqrt[3]{\rho}\cos\left(\frac{\theta+4\pi}{3}\right).\end{align*}$$

Por fim, basta subtrair $A/3$ para obter os valores de $x$. Isso conclui a dedução. Sugiro que o leitor também consulte as referências.

Referências

  • [1] LIMA, E. L. A Equação do Terceiro Grau. Revista Matemática Universitária, N. 5, Junho de 1987.
  • [2] SODRÉ, U. Raízes de equação do terceiro grau. Acesso em 28 de agosto de 2017.
  • [3] WEISSTEIN, E. W. Cubic Formula. Acesso em 28 de agosto de 2017.

Observações

Se você tiver problemas para ler o artigo, você pode obter a versão dele em PDF no seguinte link: Artigo em PDF.

Sugestões de livros para estudantes de computação na Amazon (patrocinado): Lista de Livros

Obrigado pela leitura! Se você puder, considere apoiar financeiramente o Blog Cyberini, Chave Pix: cyberpix9@gmail.com

Doar com PayPal

Siga o blog

Redes sociais: Facebook, Twitter, YouTube, Pinterest, Instagram, Telegram

Importante: utilize o bom senso na hora de comentar. Acesse a política de privacidade para maiores informações sobre comentários.

9 comentários:

  1. Que maravilha!
    Prato cheio para quem gosta de programar.
    Abraço!

    ResponderExcluir
  2. Sua solução está equivocada. As duas outras raízes devem ser obtidas a partir da divisão da equação original por y-y1.

    ResponderExcluir
    Respostas
    1. Isso está escrito no artigo "Como já conhecemos y1, então basta dividir a equação original por y−y1."

      Excluir
    2. Exato. Porém, dividiu-se y^3+py+q por y - y1, quando na verdade deveria dividir a equação x^3+Ax^2+Bx+C=0. Pode parecer a mesma coisa, mas não é. Por exemplo, testando a equação x^3 -2x^2 +3x +2 = 0, seguindo o que foi feito no seu artigo teríamos como raízes -0.478, 0.239+1.356i e 0.239-1.356i. Porém, a resposta correta seria -0.478, 1.239-1.628i e 1.239+1.628i.

      Dividindo pela equação original (a completa), eu obtive os seguintes resultados para y2 e y3:
      -(A+y1)/2 + ou - raiz((A+y1)^2-4[y1(A+y1)+B])/2 .

      Agradeço pela resposta rápida e pelo artigo, parabéns!

      Excluir
    3. Olá, inicialmente peço desculpas por ter demorado a dar uma resposta. Estou com muitos problemas ultimamente e não tenho tempo para o blog. Vamos lá.

      A equação x^3+Ax^2+Bx+C=0 está na variável x, portanto não posso dividir por y-y1.

      Referente à equação x^3 -2x^2 +3x +2 = 0, eu segui passo a passo o procedimento do blog e obtive a resposta correta x1 = −0,47796; x2 = 1.23898+1.62766i; x3 = 1.23898+1.62766i.

      Excluir
    4. Agradeço por responder. De fato seu material está correto. Eu estava calculando as raízes y2 e y3 em função do x1 (y1 + h), e não do y1. Em relação a divisão pela equação original, ou divide-se a equação y^3+py+q=0 por y - y1, ou ax^3+bx^2+cx+d=0 por x - x1, uma vez que já é conhecido o valor do x1.

      Excluir