C++: Rezolvarea Ecuației de Gradul 3

C++ Ecuația de gradul 3

Introducere

În acest articol vom implementa în C++ un program pentru rezolvarea ecuațiilor de gradul 3 de forma:

ax³ + bx² + cx + d = 0

Ecuațiile de gradul 3 sunt mai complexe decât cele de gradul 2 și necesită metode speciale de rezolvare. Vom folosi metoda Cardano, cea mai cunoscută metodă analitică pentru rezolvarea acestor ecuații.

Codul Sursă

#include <iostream>
#include <cmath>
#include <iomanip>

// Constanta PI portabila (M_PI nu e standard C++)
const double PI = std::acos(-1.0);
const double EPS = 1e-12;

/**
 * Rezolva ecuatia de gradul 3: a*x^3 + b*x^2 + c*x + d = 0
 * Metoda: Cardano (formula trigonometrica pentru Δ < 0)
 */
void rezolvaEcuatieGrad3(double a, double b, double c, double d) {
    if (std::abs(a) < EPS) {
        std::cout << "Nu este ecuatie de gradul 3!" << std::endl;
        return;
    }

    // Coeficientii redusi (substitutia x = y - b/(3a))
    double p = (3.0 * a * c - b * b) / (3.0 * a * a);
    double q = (2.0 * b * b * b - 9.0 * a * b * c
                + 27.0 * a * a * d) / (27.0 * a * a * a);
    double delta = (q * q / 4.0) + (p * p * p / 27.0);

    std::cout << "p = " << p << ", q = " << q << std::endl;
    std::cout << "Discriminant = " << delta << std::endl;

    double offset = -b / (3.0 * a);

    if (delta > EPS) {
        // O radacina reala, doua complexe
        double u = std::cbrt(-q / 2.0 + std::sqrt(delta));
        double v = std::cbrt(-q / 2.0 - std::sqrt(delta));
        double x1 = u + v + offset;
        double re = -0.5 * (u + v) + offset;
        double im = std::sqrt(3.0) / 2.0 * (u - v);

        if (std::abs(im) < EPS) im = 0.0;

        std::cout << "x1 = " << x1 << std::endl;
        std::cout << "x2 = " << re << " + " << im << "i" << std::endl;
        std::cout << "x3 = " << re << " - " << im << "i" << std::endl;

    } else if (std::abs(delta) <= EPS) {
        // Cel putin doua radacini reale egale
        if (std::abs(p) < EPS && std::abs(q) < EPS) {
            // Caz special: radacina tripla
            double x = offset;
            if (std::abs(x) < EPS) x = 0.0;
            std::cout << "x1 = x2 = x3 = " << x
                      << " (radacina tripla)" << std::endl;
        } else {
            double u = std::cbrt(-q / 2.0);
            double x_dublu = -u + offset;     // radacina dubla
            double x_simplu = 2.0 * u + offset; // radacina simpla
            if (std::abs(x_dublu) < EPS) x_dublu = 0.0;
            if (std::abs(x_simplu) < EPS) x_simplu = 0.0;
            std::cout << "x1 = x2 = " << x_dublu
                      << " (radacina dubla)" << std::endl;
            std::cout << "x3 = " << x_simplu << std::endl;
        }

    } else {
        // Trei radacini reale distincte (cazul trigonometric)
        double r = std::sqrt(-p * p * p / 27.0);
        double arg = -q / (2.0 * r);

        // Clampeaza argumentul in [-1, 1] pentru stabilitate numerica
        if (arg > 1.0) arg = 1.0;
        if (arg < -1.0) arg = -1.0;

        double theta = std::acos(arg);
        for (int i = 0; i < 3; i++) {
            double x = 2.0 * std::cbrt(r)
                     * std::cos((theta + 2.0 * PI * i) / 3.0) + offset;
            if (std::abs(x) < EPS) x = 0.0;
            std::cout << "x" << (i + 1) << " = " << x << std::endl;
        }
    }
}

int main() {
    double a, b, c, d;
    std::cout << "Introdu coeficientii a, b, c, d: ";
    std::cin >> a >> b >> c >> d;

    std::cout << "Ecuatia: " << a << "x^3 + " << b
              << "x^2 + " << c << "x + " << d << " = 0" << std::endl;
    std::cout << "Solutiile:" << std::endl;
    rezolvaEcuatieGrad3(a, b, c, d);

    return 0;
}
💡 Observație: Programul folosește metoda Cardano — cu formula trigonometrică (cosinus) pentru Δ < 0 și formula directă pentru Δ ≥ 0. Versiunea actuală include tratarea corectă a rădăcinii triple, clamping pentru acos și epsilon pentru comparații floating-point (evită NaN-urile la granița cazurilor).
⬇️ Descarcă codul sursă (ecuatie-gradul3.cpp)

Explicații Matematice

Metoda Cardano transformă ecuația de forma ax³ + bx² + cx + d = 0 printr-o substituție x = y - b/3a pentru a elimina termenul pătratic.

Apoi calculăm:

  • p = (3ac - b²) / 3a²
  • q = (2b³ - 9abc + 27a²d) / 27a³
  • Δ = q²/4 + p³/27 (discriminantul)

Cazuri:

  • Δ > 0: o rădăcină reală, două complexe
  • Δ = 0: toate rădăcinile sunt reale și cel puțin două sunt egale
  • Δ < 0: trei rădăcini reale distincte

Compilare și Rulare

Pentru a compila și rula programul:

g++ -std=c++11 -o ecuatie3 ecuatie-gradul3.cpp -lm
./ecuatie3
💡 Sfat: Pentru compilare aveți nevoie de un compilator cu suport C++11 sau mai nou (g++ 4.9+, clang++ 3.5+). Flag-ul -lm link-uiează biblioteca matematică.

Exemple de Execuție

Exemplul 1: Trei rădăcini reale distincte (x − 1)(x − 2)(x − 3) = 0

$ ./ecuatie3
Introdu coeficientii a, b, c, d: 1 -6 11 -6
Ecuatia: 1x^3 + -6x^2 + 11x + -6 = 0
Solutiile:
p = -1, q = 0
Discriminant = -0.037037
x1 = 3
x2 = 1
x3 = 2

Ecuația x³ − 6x² + 11x − 6 = 0 are rădăcinile 1, 2 și 3 — toate reale și distincte. Δ < 0, deci programul folosește cazul trigonometric (metoda cosinusului).

Exemplul 2: Rădăcină dublă — x³ − 3x + 2 = 0 → (x − 1)²(x + 2) = 0

$ ./ecuatie3
Introdu coeficientii a, b, c, d: 1 0 -3 2
Ecuatia: 1x^3 + 0x^2 + -3x + 2 = 0
Solutiile:
p = -3, q = 2
Discriminant = 0
x1 = x2 = 1 (radacina dubla)
x3 = -2

Exemplul 3: Rădăcină triplă — (x − 2)³ = x³ − 6x² + 12x − 8 = 0

$ ./ecuatie3
Introdu coeficientii a, b, c, d: 1 -6 12 -8
Ecuatia: 1x^3 + -6x^2 + 12x + -8 = 0
Solutiile:
p = 0, q = 0
Discriminant = 0
x1 = x2 = x3 = 2 (radacina tripla)

Exemplul 4: O rădăcină reală + două complexe — x³ − 1 = 0

$ ./ecuatie3
Introdu coeficientii a, b, c, d: 1 0 0 -1
Ecuatia: 1x^3 + 0x^2 + 0x + -1 = 0
Solutiile:
p = 0, q = -1
Discriminant = 0.25
x1 = 1
x2 = -0.5 + 0.866025i
x3 = -0.5 - 0.866025i
„Matematica este limbajul în care Dumnezeu a scris universul."

Concluzie

Rezolvarea ecuațiilor de gradul 3 în C++ demonstrează cum putem implementa algoritmi matematici complecși în programare. Metoda Cardano, deși complexă, oferă o soluție analitică exactă.

Pentru îmbunătățiri viitoare, poți adăuga:

  • Validarea input-ului
  • Afișarea mai frumoasă a rezultatelor
  • Tratarea completă a numerelor complexe
  • Interfață grafică