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.
Leave a Reply