De ce contează?
Gândește-te la kilometrajul vechi al unei mașini: are exact șase rotițe cu cifre. Poate arăta orice număr de la 000000 la 999999, dar nici unul mai mare — pur și simplu nu are loc. Tipurile întregi din C++ funcționează la fel: fiecare are un număr fix de „rotițe" (biți), iar acela hotărăște cât de mari pot fi numerele pe care le ține.
Ce este un tip întreg
Un tip întreg spune calculatorului doi lucruri: câtă memorie rezervă pentru o variabilă și ce interval de valori încap în ea. Memoria se măsoară în octeți (1 octet = 8 biți), iar fiecare bit e o rotiță care poate fi 0 sau 1.
Regula de bază: cu n biți poți forma 2ⁿ combinații distincte. Pentru un tip cu semn (care ține și numere negative), combinațiile se împart aproape egal:
- minimul este
−2ⁿ⁻¹ - maximul este
2ⁿ⁻¹ − 1
De aceea un int pe 32 de biți ajunge la 2³¹ − 1 = 2.147.483.647, nu la un număr „rotund". Limita nu e arbitrară — e o consecință directă a câți biți ai la dispoziție.
| Tip | Octeți | Biți | Minim | Maxim |
|---|---|---|---|---|
short | 2 | 16 | −32.768 | 32.767 |
int | 4 | 32 | −2.147.483.648 | ≈ 2,1 × 10⁹ |
long long | 8 | 64 | ≈ −9,2 × 10¹⁸ | ≈ 9,2 × 10¹⁸ |
unsigned int | 4 | 32 | 0 | ≈ 4,3 × 10⁹ |
Un tip unsigned (fără semn) nu poate ține numere negative, dar în schimb dublează maximul pozitiv — toate combinațiile merg spre numere pozitive. unsigned int ajunge la ≈ 4,3 × 10⁹ în loc de ≈ 2,1 × 10⁹.
Cum „încap" cifrele într-un octet
Un octet are 8 biți, fiecare cu o valoare de loc (128, 64, 32, …, 1), exact ca cifrele într-un număr, doar că pe bază 2. Numărul stocat e suma valorilor de loc unde bitul e 1.
| bit | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 |
| valoare | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Cu 8 biți acoperi numerele de la 0 la 255 (sau −128 la 127 dacă tipul are semn). Adaugi biți → maximul crește exponențial: fiecare bit nou dublează câte numere poți reprezenta.
Cum afli limitele în cod
Nu trebuie să le memorezi pe de rost — C++ ți le oferă prin sizeof și <climits>:
#include <iostream>
#include <climits>
using namespace std;
int main() {
cout << "int ocupa " << sizeof(int) << " octeti\n"; // 4
cout << "long long: " << sizeof(long long) << " octeti\n"; // 8
cout << "INT_MAX = " << INT_MAX << "\n"; // 2147483647
cout << "INT_MIN = " << INT_MIN << "\n"; // -2147483648
cout << "LLONG_MAX = " << LLONG_MAX << "\n"; // 9223372036854775807
return 0;
}Cum alegi tipul potrivit
Pune-ți o singură întrebare: cât de mare poate ajunge cea mai mare valoare din program? Nu doar rezultatul final, ci și calculele intermediare.
#include <iostream>
using namespace std;
int main() {
int a = 100000, b = 100000;
int gresit = a * b; // 10^10 > 2*10^9 -- OVERFLOW
long long corect = (long long)a * b; // 10000000000
cout << gresit << "\n"; // valoare gresita (negativa)
cout << corect << "\n"; // 10000000000
return 0;
}Reține regula de concurs: dacă valorile rămân sub 2 × 10⁹, int e suficient; dacă produse sau sume pot trece de atât, treci la long long.
Complexitate
Operațiile aritmetice pe întregi (+, −, *, /, %) costă O(1) — sunt instrucțiuni hardware directe, indiferent de tip. Diferența dintre int și long long nu e viteza, ci intervalul de valori. Singurul cost al lui long long e că ocupă dublu spațiu în memorie, ceea ce rareori contează.
Greșeala 1 — overflow la înmulțire: long long c = a * b; cu a, b de tip int NU e corect. Înmulțirea se face întâi în int și dă overflow ÎNAINTE de a copia în long long. Corect: long long c = (long long)a * b;
Greșeala 2 — scădere pe unsigned: unsigned x = 0; x--; nu dă −1, ci ≈ 4,3 × 10⁹. Tipurile fără semn se „înfășoară" la zero, fără nicio eroare vizibilă.
Greșeala 3 — constante mari fără sufix: long long x = 3000000000; poate da warning sau overflow, pentru că literalul e tratat ca int. Scrie 3000000000LL ca să forțezi tipul.
Greșeala 4 — presupui dimensiuni fixe: nu te baza pe „int are mereu 4 octeți" pe orice sistem. Când contează, verifică cu sizeof în loc să ghicești.
Recapitulare
- Un tip întreg fixează numărul de biți, deci și intervalul: cu
nbiți cu semn ai−2ⁿ⁻¹ … 2ⁿ⁻¹ − 1. int(4 octeți) acoperă până la ≈ 2,1 × 10⁹; pentru valori mai mari foloseștilong long(8 octeți, ≈ 9,2 × 10¹⁸).- Alegi tipul după cea mai mare valoare posibilă — inclusiv în calculele intermediare, nu doar în rezultatul final.