Biblioteca <cmath>- Materie BAC

Bun, hai să vorbim despre unul dintre cele mai utile toolbox-uri din C++: biblioteca <cmath>. Nu e doar despre matematică (cuvânt intimidant) și formule. E despre cum poți face rapid și ușor calcule complexe fără să-ți reinventezi roata de fiecare dată. E un set de unelte atât de puternic încât dacă ar fi să le scrii tu de la zero, ți-ar lua o vesnicie. Dar aici intervine și partea strategică: știi ce instrument să folosești și când.

1. Ce este <cmath>? “Cutia cu Unelte Matematice” a Programatorului

Gândește-te la ea ca la o cutie de unelte speciale pentru orice operație matematică mai avansată: poți calcula radicali, puteri, funcții trigonometrice, rotunjiri. Să înțelegem ce conține.

Ce înseamnă <cmath>?

  • <cmath> = C Math (Matematica C/C++)
  • O bibliotecă standard C++ care conține funcții matematice
  • Trebuie inclusă la începutul programului: #include <cmath>

Analogie cu o Cutie de Scule:

Ai nevoie să înșurubezi ceva? Nu-ți faci șurubelnița din lemn!
Ai nevoie să tai ceva? Nu-ți faci ferăstrăul din piatră!
La fel și în programare: ai nevoie de radical? Nu-ți scrii tu algoritmul!

Exemplu fără <cmath> vs cu <cmath>:

// FĂRĂ cmath (greu, ineficient)
double patrat = numar * numar;                      // OK, simplu
double cub = numar * numar * numar;                 // Încă OK
double puterea_a_10a = numar * numar * numar * ...  // Oh nu, de 10 ori?

// CU cmath (ușor, elegant)
#include <cmath>
double patrat = pow(numar, 2);     // numar^2
double cub = pow(numar, 3);        // numar^3  
double puterea_a_10a = pow(numar, 10);  // numar^10 - un singur apel!

2. Funcțiile ESENȚIALE din <cmath> (Cele mai folosite “unelte”)

Acestea sunt funcțiile pe care le vei folosi în 90% din cazuri.

1. pow() – Funcția PUTERE (Superputerea ta)

  • Ce face: Ridică un număr la o putere
  • Sintaxă: pow(baza, exponent)
  • Returnează: baza^exponent (baza la puterea exponent)
  • Atenție: Funcționează cu double, dar poți folosi și întregi
#include <iostream>
#include <cmath>  // NU UITA ASTA!
using namespace std;

int main() {
    // Ridicare la putere
    cout << "2 la puterea 3: " << pow(2, 3) << endl;        // 8
    cout << "5 la puterea 2: " << pow(5, 2) << endl;        // 25
    cout << "10 la puterea 0: " << pow(10, 0) << endl;      // 1 (orice^0 = 1)

    // Puteri fracționare = radicali!
    cout << "Radical din 9: " << pow(9, 0.5) << endl;       // 3 (9^(1/2))
    cout << "Radical cubic din 8: " << pow(8, 1.0/3) << endl; // 2 (8^(1/3))

    // Cu variabile
    double x = 4.5;
    int n = 3;
    double rezultat = pow(x, n);  // 4.5^3 = 91.125
    cout << x << " la puterea " << n << " = " << rezultat << endl;

    return 0;
}

Aplicație practică – Calcul dobânzii compuse:

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

int main() {
    double sumaInitiala = 1000;  // 1000 RON
    double rataDobanzii = 0.05;  // 5% pe an
    int ani = 10;                // 10 ani

    // Formula: suma = sumaInitiala * (1 + rata)^ani
    double sumaFinala = sumaInitiala * pow(1 + rataDobanzii, ani);

    cout << fixed << setprecision(2);
    cout << "Suma initiala: " << sumaInitiala << " RON\n";
    cout << "Dupa " << ani << " ani cu dobanda " << rataDobanzii*100 << "%\n";
    cout << "Vei avea: " << sumaFinala << " RON\n";

    return 0;
}

2. sqrt() – Funcția RADICAL (Specialistul în rădăcini)

  • Ce face: Calculează radicalul pătrat (√)
  • Sintaxă: sqrt(numar)
  • Returnează: √numar
  • Mai rapid decât pow(numar, 0.5) pentru radical pătrat
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    cout << "Radical din 25: " << sqrt(25) << endl;      // 5
    cout << "Radical din 2: " << sqrt(2) << endl;        // 1.41421
    cout << "Radical din 10.24: " << sqrt(10.24) << endl; // 3.2

    // ATENȚIE: sqrt(-1) = NaN (Not a Number) - eroare!
    // cout << sqrt(-1) << endl;  // Comportament nedefinit!

    // Verifică întotdeauna dacă numărul e pozitiv
    double numar = -4;
    if (numar >= 0) {
        cout << "Radical din " << numar << " = " << sqrt(numar) << endl;
    } else {
        cout << "Eroare: Nu pot calcula radical din numar negativ!\n";
    }

    return 0;
}

Aplicație practică – Teorema lui Pitagora:

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double cateta1, cateta2, ipotenuza;

    cout << "Introdu lungimea primei catete: ";
    cin >> cateta1;

    cout << "Introdu lungimea celei de-a doua catete: ";
    cin >> cateta2;

    // Ipotenuza = √(cateta1² + cateta2²)
    ipotenuza = sqrt(pow(cateta1, 2) + pow(cateta2, 2));

    cout << "Ipotenuza triunghiului dreptunghic este: " 
         << ipotenuza << endl;

    return 0;
}

3. abs() / fabs() – Funcția VALOARE ABSOLUTĂ (Eliminatorul de minus)

  • Ce face: Îndepărtează semnul minus (dacă există)
  • Diferențe: abs() pentru întregi, fabs() pentru numere reale
  • Sintaxă: abs(numarIntreg), fabs(numarReal)
#include <iostream>
#include <cmath>  // Pentru fabs()
#include <cstdlib> // Pentru abs() pentru intregi
using namespace std;

int main() {
    // Pentru întregi (din <cstdlib>)
    cout << "Valoarea absoluta a lui -5: " << abs(-5) << endl;      // 5
    cout << "Valoarea absoluta a lui 10: " << abs(10) << endl;      // 10
    cout << "Valoarea absoluta a lui 0: " << abs(0) << endl;        // 0

    // Pentru numere reale (din <cmath>)
    cout << "Valoarea absoluta a lui -3.14: " << fabs(-3.14) << endl;  // 3.14
    cout << "Valoarea absoluta a lui 2.71: " << fabs(2.71) << endl;    // 2.71

    // Aplicație: diferența dintre două numere
    double temperaturaIasi = 15.5;
    double temperaturaBucuresti = 22.3;

    double diferenta = fabs(temperaturaIasi - temperaturaBucuresti);
    cout << "Diferenta de temperatura este: " << diferenta << " grade\n";

    return 0;
}

4. Funcțiile de ROTUNJIRE – “Fă-l frumos!”

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double numar = 3.75;

    // round() - rotunjește la cel mai apropiat întreg
    cout << "round(3.75) = " << round(3.75) << endl;    // 4
    cout << "round(3.25) = " << round(3.25) << endl;    // 3
    cout << "round(3.5) = " << round(3.5) << endl;      // 4 (regula "merge up")

    // ceil() - rotunjește în sus (tavan)
    cout << "ceil(3.2) = " << ceil(3.2) << endl;        // 4
    cout << "ceil(3.8) = " << ceil(3.8) << endl;        // 4
    cout << "ceil(-3.2) = " << ceil(-3.2) << endl;      // -3 (atenție!)

    // floor() - rotunjește în jos (pardoseală)
    cout << "floor(3.8) = " << floor(3.8) << endl;      // 3
    cout << "floor(3.2) = " << floor(3.2) << endl;      // 3
    cout << "floor(-3.8) = " << floor(-3.8) << endl;    // -4 (atenție!)

    // trunc() - taie zecimale (trunchiere)
    cout << "trunc(3.8) = " << trunc(3.8) << endl;      // 3
    cout << "trunc(3.2) = " << trunc(3.2) << endl;      // 3
    cout << "trunc(-3.8) = " << trunc(-3.8) << endl;    // -3

    return 0;
}

Când folosești fiecare?

  • round() – când vrei rotunjire normală (3.5 → 4, 3.4 → 3)
  • ceil() – când vrei garantat mai mult (prețuri: 19.01 RON → 20 RON)
  • floor() – când vrei garantat mai puțin (vârsta: 17.9 ani → 17 ani)
  • trunc() – când vrei doar partea întreagă (3.99 → 3)

3. Funcții TRIGONOMETRICE – Pentru unghiuri și cercuri (la bac din ce am văzut nu s-au dat în ultimii ani, dar you never know)

Acestea sunt pentru geometrie și fizică.

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    // ATENȚIE: Funcțiile trigonometrice lucrează cu RADIANI, nu grade!
    // Conversie grade → radiani: radiani = grade * π / 180

    const double PI = 3.14159265359;

    // sin() - sinus
    double unghiGrade = 30;
    double unghiRadiani = unghiGrade * PI / 180;
    cout << "sin(" << unghiGrade << "°) = " << sin(unghiRadiani) << endl;

    // cos() - cosinus
    cout << "cos(" << unghiGrade << "°) = " << cos(unghiRadiani) << endl;

    // tan() - tangentă
    cout << "tan(45°) = " << tan(45 * PI / 180) << endl;

    // asin(), acos(), atan() - funcții inverse (arcsin, arccos, arctan)
    double valoare = 0.5;
    cout << "arcsin(0.5) in grade = " << asin(valoare) * 180 / PI << "°\n";

    return 0;
}

4. Alte funcții UTILE din <cmath>

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    // exp() - exponențială (e^x)
    cout << "e^1 = " << exp(1) << endl;           // 2.71828 (e)
    cout << "e^2 = " << exp(2) << endl;           // 7.38906

    // log() - logaritm natural (ln)
    cout << "ln(e) = " << log(exp(1)) << endl;    // 1
    cout << "ln(10) = " << log(10) << endl;       // 2.30259

    // log10() - logaritm în baza 10
    cout << "log10(100) = " << log10(100) << endl;  // 2
    cout << "log10(1000) = " << log10(1000) << endl; // 3

    // max() și min() - valorile extreme
    cout << "max(10, 20) = " << max(10, 20) << endl;  // 20
    cout << "min(10, 20) = " << min(10, 20) << endl;  // 10

    return 0;
}

5. Constante SPECIALE din <cmath>

C++ are și niște constante predefinite foarte utile:

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    // M_PI - π (3.14159265358979323846)
    cout << "Valoarea lui pi: " << M_PI << endl;

    // M_E - e (2.71828182845904523536) - baza logaritmului natural
    cout << "Valoarea lui e: " << M_E << endl;

    // Folosire în calcule
    double raza = 5;
    double arieCerc = M_PI * pow(raza, 2);
    double circumferinta = 2 * M_PI * raza;

    cout << "Pentru cerc cu raza " << raza << ":\n";
    cout << "Aria = " << arieCerc << endl;
    cout << "Circumferinta = " << circumferinta << endl;

    return 0;
}

6. PROIECT INTEGRAT: Calculator Științific Simplu

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

int main() {
    cout << "=== CALCULATOR STIINTIFIC SIMPLU ===\n\n";

    int optiune;
    double a, b, rezultat;

    do {
        cout << "\nMeniu:\n";
        cout << "1. Putere (a^b)\n";
        cout << "2. Radical patrat (√a)\n";
        cout << "3. Valoare absoluta (|a|)\n";
        cout << "4. Rotunjire\n";
        cout << "5. Arie cerc (raza a)\n";
        cout << "0. Iesire\n";
        cout << "Alege optiunea: ";
        cin >> optiune;

        switch(optiune) {
            case 1:
                cout << "Introdu baza: ";
                cin >> a;
                cout << "Introdu exponent: ";
                cin >> b;
                rezultat = pow(a, b);
                cout << a << "^" << b << " = " << rezultat << endl;
                break;

            case 2:
                cout << "Introdu numarul: ";
                cin >> a;
                if (a >= 0) {
                    rezultat = sqrt(a);
                    cout << "√" << a << " = " << rezultat << endl;
                } else {
                    cout << "Eroare: Nu pot calcula radical din numar negativ!\n";
                }
                break;

            case 3:
                cout << "Introdu numarul: ";
                cin >> a;
                rezultat = fabs(a);
                cout << "|" << a << "| = " << rezultat << endl;
                break;

            case 4:
                cout << "Introdu numarul cu zecimale: ";
                cin >> a;
                cout << "Rotunjit normal: " << round(a) << endl;
                cout << "Rotunjit in sus: " << ceil(a) << endl;
                cout << "Rotunjit in jos: " << floor(a) << endl;
                break;

            case 5:
                cout << "Introdu raza cercului: ";
                cin >> a;
                rezultat = M_PI * pow(a, 2);
                cout << fixed << setprecision(2);
                cout << "Aria cercului cu raza " << a << " = " << rezultat << endl;
                break;

            case 0:
                cout << "La revedere!\n";
                break;

            default:
                cout << "Optiune invalida!\n";
        }

    } while(optiune != 0);

    return 0;
}

7. ERORI COMUNE și Cum Să Le Evităm

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    // 1. UITI să incluzi <cmath>
    // cout << pow(2, 3); // EROARE: pow nu este definit

    // 2. Confuzii cu tipurile de date
    int a = 2;
    int b = 3;

    // pow() returnează double, dar poți pierde precizie
    int rezultatGresit = pow(a, b);  // OK, dar conversie la int
    double rezultatCorect = pow(a, b); // Mai bine!

    // 3. Radical din număr negativ
    // double r = sqrt(-4); // EROARE la execuție

    // 4. Rotunjire cu numere negative
    cout << "ceil(-3.2) = " << ceil(-3.2) << endl;  // -3, nu -4!
    cout << "floor(-3.2) = " << floor(-3.2) << endl; // -4, nu -3!

    // 5. Funcții trigonometrice cu grade în loc de radiani
    double grade = 90;
    // GREȘIT: cout << sin(90) << endl; // 90 radiani!
    // CORECT: cout << sin(grade * M_PI / 180) << endl;

    return 0;
}

În concluzie, să-ți spun ceva practic:

Biblioteca <cmath> este comoara ascunsă a programatorului C++. Transformă probleme matematice complexe în simple apeluri de funcții. E cel mai bun prieten al tău când ai de-a face cu calcule mai avansate.

Dar folosirea greșită a acestor funcții poate fi, paradoxal, o sursă de erori subtile dacă nu înțelegi exact ce face fiecare funcție și ce parametri așteaptă.

Așa că ai grijă ce funcție alegi. Cunoștințe-ti nevoile: ai nevoie de putere sau radical? De rotunjire sau valoare absolută? Pentru că puterea de a face calcule complexe este goală fără abilitatea de a alege funcția corectă pentru sarcina corectă. Și această putere vine cu o responsabilitate: să fii precis și atent la detalii.

Folosirea corectă a bibliotecii <cmath> este o parte integrală a programării eficiente și precise. Ai grijă de ea cu aceeași seriozitate.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *