Sari la conținut

Capitolul 3 · Lecția 3.2 din 2

Limitele tipurilor și depășirea (overflow)

Cât încape în int și long long, ce se întâmplă la depășire și cum o eviți.

Capitolul 3: Tipuri de date și variabileConținut verificat

Pe scurt pentru BAC · 4 idei

  • int ocupă 4 octeți și ține valori între aproximativ −2⋅109-2 \cdot 10^9 și 2⋅1092 \cdot 10^9, iar long long ocupă 8 octeți.
  • Depășirea lui int nu dă eroare la rulare: valoarea se înfășoară, iar rezultatul devine absurd.
  • Sufixul 1LL din 1LL * a * b forțează calculul pe 64 de biți încă de la primul pas.
  • Realele se reprezintă aproximativ, așa că 0.1 + 0.2 == 0.3 e fals, iar comparațiile se fac cu toleranță, ca fabs(x - y) < 1e-9.
Pe această pagină5 secțiuni

Limitele care trebuie știute

TipDimensiuneInterval aproximativ
int4 octeți−2⋅109…2⋅109-2 \cdot 10^9 \ldots 2 \cdot 10^9 (exact ±2147483647\pm 2147483647)
long long8 octeți±9,2⋅1018\pm 9{,}2 \cdot 10^{18}
char1 octetun caracter (codul 0-255 / -128..127)
double8 octețireale, ~15 cifre semnificative

Regula practică: peste ~2 miliarde → long long; numărul de cifre al lui n! sau produse mari → tot long long sau regândirea algoritmului.

Overflow: ce se întâmplă la depășire

Depășirea lui int NU dă eroare la rulare: valoarea "se înfășoară" (comportament de aritmetic modular), rezultatul devine absurd, adesea NEGATIV.

Exemplu clasic. int a = 2000000000; a + a nu dă 4 miliarde, ci un număr negativ: 4·10⁹ nu încape în int.

Capcana subtilă: produsul a doi int

Depasirea tipului intreg

#include <iostream>
using namespace std;

int main() {
    int a = 100000, b = 100000;
    long long gresit = a * b;
    cout << gresit;
    return 0;
}

Atenție: Singurul loc din lectii unde cele patru limbaje dau intentionat rezultate diferite, fiindca despre asta e lectia. In C si C++ inmultirea se face intre doi int si depaseste tipul INAINTE de a fi pusa in variabila mare, deci iese 1410065408. Pascal ridica automat calculul la int64 si da rezultatul corect, iar Python nu are nicio limita la intregi. Deci aceeasi greseala de gandire se pedepseste in C si C++, dar trece nepedepsita in celelalte doua.

se trimit programului la citire

GREȘIT: a * b se calculează ÎN int (overflow), abia apoi se copiază în long long. Corect:

Cum se evita depasirea

#include <iostream>
using namespace std;

int main() {
    int a = 100000, b = 100000;
    long long corect = 1LL * a * b;
    cout << corect;
    return 0;
}

Atenție: Inmultirea cu 1LL in C si C++, sau conversia la int64 in Pascal, forteaza calculul sa se faca de la inceput pe tipul mare. In Python nu e nevoie de nimic.

se trimit programului la citire

Sufixul 1LL forțează calculul pe 64 de biți de la primul pas.

double: capcana comparării

Realele se reprezintă aproximativ: 0.1 + 0.2 == 0.3 e FALS în C++. Comparațiile de reale se fac cu toleranță: fabs(x - y) < 1e-9.

Reține

int ≈ ±2·10⁹, long long ≈ ±9·10¹⁸. La produse: 1LL * a * b. Depășirea nu anunță: rezultate negative "din senin" = simptomul clasic.

Greșeli frecvente

  1. Suma a n numere de până la 10⁹: pentru n ≥ 3 rezultatul cere long long.
  2. long long p = a * b cu a, b int NU te salvează: conversia vine prea târziu.
  3. La double, egalitatea strictă e nesigură: folosește toleranță.

Instrumente pentru lecția asta

Conversii între baze

Zecimal → binar prin împărțiri repetate, cu resturile evidențiate, verificarea prin puterile lui 2 și echivalentul hexazecimal.

Se încarcă instrumentul…

Bifează când ai terminat, ca s-o vezi citită pe toate dispozitivele.

Testează-te pe capitolul 3

Lecția în clipuri

Clipuri scurte, cu voce și subtitrări.

Folosim cookie-uri esențiale, fără de care site-ul nu merge, și cookie-uri de analiză anonimizate, ca să vedem ce pagini ajută. Detalii în politica de confidențialitate