De ce contează?
Gândește-te la kilometrajul unei mașini vechi, cel mecanic, cu rotițe. Are exact 6 rotițe, deci poate arăta cel mult 999999 km. Când treci de atât, rotițele nu cresc magic la 7 — se învârt înapoi la 000000. Numărul de rotițe e fix, deci intervalul de numere pe care le poate afișa e fix. Tipurile întregi din C++ funcționează la fel: fiecare are un număr fix de „rotițe" (biți), deci un interval fix de valori pe care le poate ține.
Ce este
Un tip întreg îi spune calculatorului două lucruri despre o variabilă: că păstrează numere fără virgulă (3, -7, 0, 1000000) și cât spațiu rezervă pentru ea în memorie. Spațiul se măsoară în biți, iar de el depinde direct cât de mari pot fi numerele.
Cele două tipuri pe care le vei folosi cel mai des:
int— 32 de biți. Ține numere de la aproximativ -2 miliarde la +2 miliarde (mai exact, până la 2147483647). E alegerea normală pentru numere „obișnuite": un index, o vârstă, un scor, n elemente.long long— 64 de biți. Ține numere de la aproximativ -9.2 miliarde de miliarde la +9.2 miliarde de miliarde (mai exact, până la 9223372036854775807). Îl scoți la înaintare când numerele cresc peste limita luiint.
Mai există și unsigned (fără semn): renunță complet la numerele negative și folosește tot spațiul pentru valori pozitive. Un unsigned int ajunge astfel până la aproximativ 4.2 miliarde, dublul plafonului pozitiv al lui int — dar nu poate ține niciun număr negativ.
De ce există o limită deloc? Pentru că biții sunt în număr fix. Cu 32 de biți poți scrie un număr finit de combinații de 0 și 1, deci un număr finit de valori. Mai mulți biți înseamnă mai multe combinații, deci un interval mai mare. long long are de două ori mai mulți biți decât int, dar intervalul nu se dublează — se ridică la o putere mult mai mare. Asta nu e magie, e doar câte numere distincte încap.
Cum arată
Hai să punem cele trei tipuri unul lângă altul și să vedem până unde ajunge fiecare. Numerele de jos sunt plafonul pozitiv aproximativ al fiecărui tip.
32-biti | 32-biti-fara-semn | 64-biti |
int | unsigned | long-long |
~2.1-miliarde | ~4.2-miliarde | ~9.2-miliarde-de-miliarde |
Ca să simți diferența cu numere concrete, gândește-te ce încape și ce nu:
| Numărul | Încape în int? | Ai nevoie de long long? |
|---|---|---|
| Populația unui oraș (2 milioane) | Da | Nu |
| Numărul de secunde într-un an (31536000) | Da | Nu |
| Distanța Pământ–Soare în km (150 de milioane) | Da | Nu |
| Numărul de secunde de la anul 0 (peste 60 de miliarde) | Nu | Da |
| Suma a 100000 de numere, fiecare până la (până la ) | Nu | Da |
Observă tiparul: atâta timp cât numerele tale stau sub câteva miliarde, int e perfect. În momentul în care înmulțești sau aduni multe numere mari, treci ușor de 2 miliarde și ai nevoie de long long.
Implementare C++
Programul de mai jos arată exact momentul în care int nu mai face față, dar long long da.
#include <iostream>
using namespace std;
int main() {
// n numere, fiecare poate fi pana la un miliard
int n = 100000;
int valoare = 1000000000; // 10^9, incape lejer in int
// GRESIT: suma calculata in int
// 100000 * 10^9 = 10^14, mult peste limita int (~2.1 miliarde)
int suma_gresita = 0;
for (int i = 0; i < n; i++) {
suma_gresita += valoare; // depaseste int, rezultat aiurea
}
// CORECT: suma calculata in long long
long long suma_buna = 0;
for (int i = 0; i < n; i++) {
suma_buna += valoare; // 100000000000000 (10^14), incape in long long
}
cout << "Suma in int: " << suma_gresita << "\n"; // numar gresit
cout << "Suma in long long: " << suma_buna << "\n"; // 100000000000000
return 0;
}Reține forma: declari tipul în fața numelui variabilei. int n; rezervă 32 de biți; long long suma; rezervă 64. Diferența nu se vede în cum scrii codul, ci în cât de mari pot deveni valorile fără să se strice.
Capcana numărul unu la concurs: declari int suma; și aduni în ea multe numere mari. Fiecare număr în parte încape în int, deci totul pare în regulă — dar suma depășește 2 miliarde și valoarea devine aiurea (uneori chiar negativă). Programul nu dă nicio eroare, pur și simplu scrie un rezultat greșit, și pici exact testele cu n mare. Regula de aur: dacă aduni sau înmulțești numere care, însumate, pot trece de 2 miliarde, folosește long long pentru rezultat de la bun început. Costă aproape nimic în plus și te scutește de cea mai frecventă greșeală din toate concursurile.