double, float în C++

Tipuri pentru numere reale (cu zecimale): double are aproximativ 15-16 cifre exacte, float doar 6-7.

Sintaxă
double d = 3.14;    // dublă precizie, 8 octeți
float f = 3.14f;    // simplă precizie, 4 octeți

Ce face double, float

Pentru prețuri, medii, temperaturi și orice număr cu virgulă folosești double. În cod, separatorul zecimal este punctul: 4.5, nu 4,5. float ocupă jumătate din memorie, dar este mult mai puțin precis; folosește-l doar când ai milioane de valori (grafică, jocuri).

Un literal ca 3.14 este double; pentru float adaugă sufixul f: 3.14f. Există și long double, care pe unele sisteme are mai multă precizie (pe macOS cu Apple M este identic cu double).

Numerele reale sunt păstrate în binar, așa că multe valori zecimale nu pot fi reprezentate exact. 0.1 + 0.2 nu este exact 0.3.

Exemple

Exemplul 1: Calcule cu zecimale

#include <print>

int main() {
    double pret = 49.99;
    int bucati = 3;
    double total = pret * bucati;
    std::println("Total: {} lei", total);
    std::println("Total rotunjit: {:.2f} lei", total);
    std::println("Media notelor 9, 10, 8: {:.2f}", (9 + 10 + 8) / 3.0);
}

Rezultat

Total: 149.97 lei
Total rotunjit: 149.97 lei
Media notelor 9, 10, 8: 9.00

Exemplul 2: Precizia: 0.1 + 0.2

std::println afișează cel mai scurt text care reprezintă exact valoarea păstrată, deci se vede eroarea de rotunjire. Compară numerele reale cu o toleranță, nu cu ==.

#include <cmath>
#include <print>

int main() {
    double suma = 0.1 + 0.2;
    std::println("0.1 + 0.2 = {}", suma);
    std::println("Egal cu 0.3? {}", suma == 0.3);
    std::println("Aproape egal? {}", std::abs(suma - 0.3) < 1e-9);
}

Rezultat

0.1 + 0.2 = 0.30000000000000004
Egal cu 0.3? false
Aproape egal? true

Exemplul 3: float față de double

Afișat cu 10 zecimale, float-ul arată că a păstrat doar o aproximare a lui 0.1.

#include <print>

int main() {
    float f = 0.1f;
    double d = 0.1;
    std::println("float:  {:.10f} ({} octeți)", f, sizeof(f));
    std::println("double: {:.10f} ({} octeți)", d, sizeof(d));
}

Rezultat

float:  0.1000000015 (4 octeți)
double: 0.1000000000 (8 octeți)

Greșeli frecvente

  • Folosești double pentru bani în aplicații de contabilitate. Erorile mici de rotunjire se adună; ține sumele în bani (întregi, de exemplu în long long) și împarte la 100 doar la afișare.
  • Scrii double media = suma / numar; cu suma și numar de tip int. Împărțirea se face întâi între întregi (și pierde zecimalele), abia apoi rezultatul devine double.
  • Compari cu == rezultate de calcul: if (0.1 + 0.2 == 0.3) este fals. Compară diferența cu o toleranță mică.

Comenzi înrudite

  • int: Tipul de bază pentru numere întregi (fără zecimale), de obicei pe 4 octeți, cu valori între aproximativ -2,1 și 2,1 miliarde.
  • auto: Lasă compilatorul să deducă tipul variabilei din valoarea cu care este inițializată.
  • static_cast, dynamic_cast, const_cast, reinterpret_cast: Cele patru conversii explicite: static_cast (obișnuite), dynamic_cast (clase), const_cast (const) și reinterpret_cast (biți).
  • sizeof: Dă numărul de octeți ocupați în memorie de un tip sau de o variabilă; se calculează la compilare.
  • std::format: Construiește un std::string dintr-un șablon cu acolade {} și valori (C++20).