De ce contează?
Ai un program care calculează produsul a două numere de 100.000. Scrii int produs = a * b;, compilatorul nu protestează, programul rulează — și afișează un număr negativ. Nicio eroare, rezultat complet greșit. Asta e overflow: depășești limita tipului și valoarea „se înfășoară". Alegerea tipului potrivit nu e un detaliu — previne o categorie întreagă de bug-uri silențioase.
Tipurile întregi în C++
C++ oferă mai multe tipuri pentru numere întregi, diferite prin spațiul ocupat și intervalul de valori:
| Tip | Biți | Minim | Maxim |
|---|---|---|---|
short | 16 | −32.768 | 32.767 |
int | 32 | −2.147.483.648 | 2.147.483.647 |
long long | 64 | −9,2 × 10¹⁸ | 9,2 × 10¹⁸ |
unsigned int | 32 | 0 | 4.294.967.295 |
Regula de la concursuri: dacă n ≤ 10⁹, int e suficient. Dacă produse sau sume pot ajunge la 10¹⁸, folosești long long. Atenție: produsul a două valori de 10⁹ e 10¹⁸ — depășește int chiar dacă fiecare factor în parte încăpea în int.
Overflow — cel mai frecvent bug la concursuri
Overflow se întâmplă când o valoare depășește maximul tipului. Calculul continuă fără eroare, dar rezultatul e greșit.
#include <iostream>
using namespace std;
int main() {
int a = 100000;
int b = 100000;
int produs = a * b; // 10^10 > 2*10^9 -- OVERFLOW!
long long produsCorect = (long long)a * b; // corect: 10000000000
cout << produs << endl; // rezultat gresit (negativ!)
cout << produsCorect << endl; // 10000000000
return 0;
}Conversia (cast) între tipuri
int a = 5, b = 2;
int cat1 = a / b; // 2 (impartire intreaga)
double cat2 = (double)a / b; // 2.5 (cast explicit)
long long mare = (long long)a * 1000000000; // fortat la 64 bitiConstante utile
#include <climits>
cout << INT_MAX << endl; // 2147483647
cout << INT_MIN << endl; // -2147483648
cout << LLONG_MAX << endl; // 9223372036854775807Când inițializezi un maxim sau minim pentru comparație, folosește INT_MAX / INT_MIN în loc de valori arbitrare ca 999999999 — e mai sigur și mai clar.
Complexitate
Operațiile aritmetice pe întregi costă O(1) — sunt instrucțiuni hardware directe.
Greșeala 1: Înmulțești doi int mari și stochezi în long long, crezând că e suficient. long long c = a * b; NU e corect dacă a și b sunt int — înmulțirea se face în int și dă overflow ÎNAINTE ca rezultatul să fie copiat în long long. Corect: long long c = (long long)a * b;
Greșeala 2: Folosești unsigned și scazi mai mult decât ai. unsigned x = 0; x--; nu dă −1, ci 4.294.967.295 — înfășurare la zero, fără nicio eroare vizibilă.
Greșeala 3: Uiți sufixul LL la constante literale mari. long long x = 3000000000; poate da overflow sau warning — scrie 3000000000LL pentru a forța tipul corect.