C# - Calculando as raizes de uma equação cúbica


Hoje veremos um exemplo de como calcular as raizes de uma equação cúbica usando a linguagem C#.

Na Matemática, uma equação cúbica ou equação do terceiro grau é uma equação polinomial de grau três. Qualquer equação de 3° grau pode ser escrita da seguinte forma:   A x^3 + B x^2 + C x + D = 0

Gerolamo Cardano publicou um método para resolver uma equação cúbica em 1545 que você pode conferir na Wikipedia.

Vamos fazer uma implementação deste cálculo usando os recursos da linguagem C# em um projeto Windows Forms.

Criando o projeto Windows Forms

Vamos então criar um projeto do tipo Windows Forms App(.NET Framework) no VS 2019 Community no menu File -> New Project, com o nome EquacaoCubica;

No formulário Form1.cs inclua os seguintes controles:

Defina o leiaute do formulário conforme a imagem a seguir:

No formulário vamos criar um método CalculaRaizCubica() com o código abaixo:

       private void CalculaRaizCubica()
        {
            try
            {
                //coeficientes
                double a = double.Parse(TxtCubA.Text);
                double b = double.Parse(TxtCubB.Text);
                double c = double.Parse(TxtCubC.Text);
                double d = double.Parse(TxtCubD.Text);
                //equação
                double f = (((3 * c) / a) - ((b * b) / (a * a))) / 3;

                string f2 = f.ToString();
                double g = (((2 * (Math.Pow(b, 3))) / (Math.Pow(a, 3))) - ((9 * b * c) / (Math.Pow(a, 2))) + ((27 * d) / a)) / 27;
                string g2 = g.ToString();
                double h = ((Math.Pow(g, 2)) / 4) + ((Math.Pow(f, 3)) / 27);
                string h2 = h.ToString();

                if (h <= 0)
                {
                    double i = (((Math.Pow(g, 2)) / 4) - h);
                    double i2 = Math.Pow(i, 0.5);
                    string i3 = i2.ToString();
                    double j = (Math.Pow(i2, 0.333333333333333333333333));
                    string j2 = j.ToString();
                    double k = ((Math.Acos(0 - (g / (2 * i2)))));
                    string k2 = k.ToString();
                    double l = (j * (0 - 1));
                    string l2 = l.ToString();
                    double m = ((Math.Cos(k / 3)));
                    string m2 = m.ToString();
                    double n = ((Math.Pow(3, 0.5)) * Math.Sin(k / 3));
                    string n2 = n.ToString();
                    double p = ((b / (3 * a)) * (0 - 1));
                    string p2 = p.ToString();
                    double x = ((2 * j) * (Math.Cos(k / 3)) - (b / (3 * a)));
                    string x2 = x.ToString();
                    TxtCubx1.Text = x2;
                    double y = (l * (m + n) + p);
                    string y2 = y.ToString();
                    TxtCubx2.Text = y2;
                    double z = (l * (m - n) + p);
                    string z2 = z.ToString();
                    TxtCubx3.Text = z2;
                }

                if (h > 0)
                {
                    double u = 0 - g;
                    double r = (u / 2) + (Math.Pow(h, 0.5));
                    string r2 = r.ToString();
                    if (r >= 0)
                    {
                        double s6 = (Math.Pow(r, 0.333333333333333333333333333));
                        double s8 = s6;
                        string s9 = s8.ToString();

                        double t8 = (u / 2) - (Math.Pow(h, 0.5));
                        string t9 = t8.ToString();
                        double help8 = (1.0 / 3);
                        string help9 = help8.ToString();
                        if (t8 < 0)
                        {
                            double v7 = (Math.Pow((0 - t8), 0.33333333333333333333));
                            double v8 = (v7);
                            string v9 = v8.ToString();
                            double x3 = (s8 - v8) - (b / (3 * a));
                            string x4 = x3.ToString();
                            TxtCubx1.Text = x4;
                            double y3 = ((0 - (s8 - v8)) / 2) - (b / (3 * a));
                            double y4 = ((s8 + v8) * (Math.Sqrt(3) / 2));
                            string y6 = y3.ToString();
                            string y7 = y4.ToString();
                            TxtCubx2.Text = y6 + " + " + y7 + "i";
                            double z3 = ((0 - (s8 - v8)) / 2) - (b / (3 * a));
                            double z4 = ((s8 + v8) * (Math.Sqrt(3)) / 2);
                            string z6 = z3.ToString();
                            string z7 = z4.ToString();
                            TxtCubx3.Text = z6 + " - " + z7 + "i";

                        }
                        if (t8 >= 0)
                        {
                            double v6 = (Math.Pow((0 - (0 - t8)), 0.33333333333333333333));
                            double v5 = (v6);
                            string v4 = v5.ToString();
                            double x3 = (s8 + v5) - (b / (3 * a));
                            string x4 = x3.ToString();
                            TxtCubx1.Text = x4;
                            double y3 = ((0 - (s8 + v5)) / 2) - (b / (3 * a));
                            double y4 = ((s8 - v5) * (Math.Sqrt(3) / 2));
                            string y6 = y3.ToString();
                            string y7 = y4.ToString();
                            TxtCubx2.Text = y6 + " + " + y7 + "i";
                            double z3 = ((0 - (s8 + v5)) / 2) - (b / (3 * a));
                            double z4 = ((s8 - v5) * (Math.Sqrt(3)) / 2);
                            string z6 = z3.ToString();
                            string z7 = z4.ToString();
                            TxtCubx3.Text = z6 + " - " + z7 + "i";
                        }
                    }
                    if (r < 0)
                    {
                        double s3 = (Math.Pow((0 - r), 0.333333333333333333333333333));
                        double s = (0 - s3);
                        string s2 = s.ToString();

                        double t = (u / 2) - (Math.Pow(h, 0.5));
                        string t2 = t.ToString();
                        double help = (1.0 / 3);
                        string help2 = help.ToString();
                        if (t < 0)
                        {
                            double v = (Math.Pow((0 - t), 0.33333333333333333333));
                            double v2 = (v);
                            string v3 = v2.ToString();
                            double x3 = (s - v2) - (b / (3 * a));
                            string x4 = x3.ToString();
                            TxtCubx1.Text = x4;
                            double y3 = ((0 - (s - v2)) / 2) - (b / (3 * a));
                            double y4 = ((s + v2) * (Math.Sqrt(3) / 2));
                            string y6 = y3.ToString();
                            string y7 = y4.ToString();
                            TxtCubx2.Text = y6 + " + " + y7 + "i";
                            double z3 = ((0 - (s - v2)) / 2) - (b / (3 * a));
                            double z4 = ((s + v2) * (Math.Sqrt(3)) / 2);
                            string z6 = z3.ToString();
                            string z7 = z4.ToString();
                            TxtCubx3.Text = z6 + " - " + z7 + "i";
                        }
                        if (t >= 0)
                        {
                            double v = (Math.Pow((0 - (0 - t)), 0.33333333333333333333));
                            double v2 = (v);
                            string v3 = v2.ToString();
                            double x3 = (s + v2) - (b / (3 * a));
                            string x4 = x3.ToString();
                            TxtCubx1.Text = x4;
                            double y3 = ((0 - (s + v2)) / 2) - (b / (3 * a));
                            double y4 = ((s - v2) * (Math.Sqrt(3) / 2));
                            string y6 = y3.ToString();
                            string y7 = y4.ToString();
                            TxtCubx2.Text = y6 + " + " + y7 + "i";
                            double z3 = ((0 - (s + v2)) / 2) - (b / (3 * a));
                            double z4 = ((s - v2) * (Math.Sqrt(3)) / 2);
                            string z6 = z3.ToString();
                            string z7 = z4.ToString();
                            TxtCubx3.Text = z6 + " - " + z7 + "i";
                        }
                    }
                }
                if (h == 0 && f == 0 && g == 0)
                {
                    double x5 = ((Math.Pow((d / a), 0.3333333333333333333))) * (0 - 1);
                    string x6 = x5.ToString();
                    TxtCubx1.Text = x6;
                    TxtCubx2.Text = x6;
                    TxtCubx3.Text = x6;
                }
            }
            catch {throw;}
        }

Essa abordagem, embora esteja funcionando, não é uma boa prática. O correto seria criar uma classe e definir métodos para realizar as operações recebendo os parâmetros usados. Fica como um exercício.

No evento Click do botão de comando - Calcular raizes da equação -  inclua o código para fazer o cálculo das raízes:

private void BtnCalcular_Click(object sender, EventArgs e)
{
            CalculaRaizCubica();
}

No evento TextChanged dos TextBox das raizes inclua o código abaixo:

     private void TxtCubx1_TextChanged(object sender, EventArgs e)
        {
            if (TxtCubx1.Text.Contains("i"))
            {
                TxtCubx1.ForeColor = Color.Red;
            }
            else
            {
                TxtCubx1.ForeColor = Color.Black;
            }
        }
        private void TxtCubx2_TextChanged(object sender, EventArgs e)
        {
            if (TxtCubx2.Text.Contains("i"))
            {
                TxtCubx2.ForeColor = Color.Red;
            }
            else
            {
                TxtCubx2.ForeColor = Color.Black;
            }
        }
        private void TxtCubx3_TextChanged(object sender, EventArgs e)
        {
            if (TxtCubx3.Text.Contains("i"))
            {
                TxtCubx3.ForeColor = Color.Red;
            }
            else
            {
                TxtCubx3.ForeColor = Color.Black;
            }
        }

Este código vai verificar se o resultado da raiz contém 'i' de imáginário e vai alterar a cor para vermelho, caso contrário vai exibir na cor preta.

A nossa implementação com certeza não é a prova de balas e poderá ser melhorada em muitos aspectos mas funciona para as equações mais simples.

Executando o projeto e fazendo um teste para a equação :  x^3 - 6x + 9  temos

Pegue o projeto completo aqui : EquacaoCubica.zip

"Vós me chamais Mestre e Senhor, e dizeis bem, porque eu o sou.
Ora, se eu, Senhor e Mestre, vos lavei os pés, vós deveis também lavar os pés uns aos outros.
Porque eu vos dei o exemplo, para que, como eu vos fiz, façais vós também."
João 13:13-15

 Referências:


José Carlos Macoratti