Reprezentarea numerelor în memorie

Mediu~14 min5 pași

De ce contează?

Un contor de kilometri are un număr fix de cifre. Când trece de 999999, se întoarce la 000000 — nu pentru că e stricat, ci pentru că n-are loc de mai multe cifre. Memoria calculatorului păstrează numerele exact așa: pe un număr fix de biți, cu aceeași „rostogolire" la depășire.

Bit, octet, cuvânt

  • Un bit e cea mai mică unitate: 0 sau 1.
  • Un octet (byte) = 8 biți.
  • Un int ocupă tipic 4 octeți = 32 de biți.

Cu k biți reprezinți 2ᵏ valori distincte. Pentru 32 de biți: 2³² ≈ 4,3 miliarde de combinații.

Cum „arată" un număr în memorie

Numărul 11 stocat pe 8 biți (ca să încapă în diagramă) e binarul lui, completat cu zerouri la stânga:

biți
0
0
0
0
1
0
1
1
valoare
128
64
32
16
8
4
2
1
11 pe 8 biți: 00001011. Aduni valorile pozițiilor cu bit 1: 8 + 2 + 1 = 11. Restul biților sunt 0.

De ce limita: un bit pleacă pe semn

Pentru numere cu semn, un bit indică semnul (+/−). Rămân 31 de biți pentru valoare, deci intervalul int e aproximativ:

TipBițiInterval
int32−2,1 mld ... +2,1 mld
unsigned int320 ... ~4,3 mld
long long64±9,2 · 10¹⁸
Observația-cheie

unsigned renunță la numere negative și folosește toți biții pentru valori pozitive, dublând maximul. Dar atenție: scăderea sub 0 la unsigned se rostogolește la un număr uriaș, nu dă negativ.

Overflow: rostogolirea kilometrajului

Când aduni 1 la maximul unui int, nu mai e loc — valoarea sare la minimul negativ:

#include <iostream>
using namespace std;

int main() {
    int maxim = 2147483647;     // cel mai mare int
    cout << maxim + 1 << "\n";  // -2147483648 (overflow!)
    return 0;
}

Niciun mesaj de eroare — doar un rezultat greșit. De aici regula: dacă valorile pot trece de ~2 miliarde, folosește long long.

sizeof — câți octeți ocupă

cout << sizeof(int) << "\n";        // 4
cout << sizeof(long long) << "\n";  // 8
cout << sizeof(char) << "\n";       // 1

Complexitate

Reprezentarea nu are „timp de execuție" — e doar mod de stocare. Dar alegerea tipului afectează memoria: un vector de un milion de long long ocupă 8 MB, dublu față de int.

Greșeli frecvente

Capcane reale la reprezentarea în memorie:

  • Overflow tăcut: depășești int și primești un rezultat negativ „din senin", fără eroare. Verifică dacă valorile încap; folosește long long.
  • unsigned sub zero: unsigned x = 0; x - 1 dă ~4,3 miliarde, nu −1.
  • Presupui dimensiuni fixe: int e tipic 32 de biți, dar standardul garantează doar minimul. Pentru certitudine la dimensiuni, există tipuri ca int32_t, int64_t.
  • Risipă de memorie: long long peste tot, când int ar ajunge, poate depăși limita de memorie a problemei.

De reținut

  • 1 octet = 8 biți; int = tipic 32 de biți → ±2,1 miliarde cu semn.
  • Un bit pleacă pe semn; unsigned dublează maximul, dar nu are negative.
  • Overflow = rostogolire tăcută la minimul negativ → peste ~2 mld folosește long long.

Întrebarea 1 / 3

Câți biți are de obicei un `int` în C++?