double și float în Java

Tipurile pentru numere cu virgulă: double (64 de biți, implicit) și float (32 de biți, literal cu sufixul f).

Sintaxă
double pret = 19.99;   // 64 de biți, ~15-16 cifre exacte
float medie = 9.5f;    // 32 de biți, ~7 cifre exacte
double mare = 1.5e6;   // 1.500.000

Ce face double și float

double și float păstrează numere reale în virgulă mobilă (standardul IEEE 754). double are aproximativ 15-16 cifre semnificative și este tipul implicit: 3.14 este double. float are doar aproximativ 7 cifre și literalul are nevoie de sufixul f.

Multe zecimale nu se pot reprezenta exact în binar, de aceea 0.1 + 0.2 dă 0.30000000000000004. Pentru bani folosește BigDecimal sau lucrează în bani (întregi). Compară valorile double cu o toleranță, nu cu ==.

Împărțirea la zero cu double nu aruncă excepție: dă Infinity, -Infinity sau NaN (Not a Number, pentru 0.0 / 0.0).

Parametri

Parametru Descriere
double 64 de biți, aproximativ ±1,8·10308. Alegerea obișnuită.
float 32 de biți, aproximativ ±3,4·1038. Literal cu f: 2.5f.

Exemple

Exemplul 1: Calcule și formatare

String.format cu %.2f afișează două zecimale (rotunjite). Rezultatul brut al înmulțirii are zecimalele erorii de reprezentare.

public class Main {
    public static void main(String[] args) {
        double pret = 19.99;
        int bucati = 3;
        double total = pret * bucati;
        System.out.println("total brut: " + total);
        System.out.println("total afișat: " + String.format("%.2f", total) + " lei");

        double tva = total * 0.21;
        System.out.printf("TVA 21%%: %.2f lei%n", tva);
        System.out.println("notație științifică: " + 1.5e6);
    }
}

Rezultat

total brut: 59.97
total afișat: 59.97 lei
TVA 21%: 12.59 lei
notație științifică: 1500000.0

Exemplul 2: Precizia limitată

0.1 + 0.2 nu este exact 0.3, deci == dă false. Compararea cu o toleranță mică rezolvă problema. float păstrează mai puține cifre decât double.

public class Main {
    public static void main(String[] args) {
        double a = 0.1 + 0.2;
        System.out.println("0.1 + 0.2 = " + a);
        System.out.println("egal cu 0.3? " + (a == 0.3));
        System.out.println("aproape egal? " + (Math.abs(a - 0.3) < 1e-9));

        float f = 1.1234567890f;
        double d = 1.1234567890;
        System.out.println("float:  " + f);
        System.out.println("double: " + d);
    }
}

Rezultat

0.1 + 0.2 = 0.30000000000000004
egal cu 0.3? false
aproape egal? true
float:  1.1234568
double: 1.123456789

Exemplul 3: Infinity și NaN

Cu double, împărțirea la zero nu oprește programul. NaN nu este egal nici cu el însuși, de aceea se verifică cu Double.isNaN.

public class Main {
    public static void main(String[] args) {
        double km = 120.0;
        System.out.println(km / 0);
        System.out.println(-km / 0);

        double nedefinit = 0.0 / 0.0;
        System.out.println(nedefinit);
        System.out.println("NaN == NaN? " + (nedefinit == nedefinit));
        System.out.println("isNaN? " + Double.isNaN(nedefinit));
    }
}

Rezultat

Infinity
-Infinity
NaN
NaN == NaN? false
isNaN? true

Greșeli frecvente

  • float f = 2.5; nu compilează: 2.5 este double. Scrie 2.5f.
  • Compararea cu == a rezultatelor calculelor cu zecimale.
  • Sume de bani păstrate în double: erorile de rotunjire se adună. Folosește BigDecimal sau întregi (bani).

Comenzi înrudite

  • int, long, short și byte: Tipurile întregi din Java: int (32 de biți) pentru aproape orice, long pentru valori mari, short și byte pentru economie de memorie.
  • Variabile și tipuri primitive: O variabilă are un tip fix, declarat la creare; Java are 8 tipuri primitive: byte, short, int, long, float, double, char, boolean.
  • Operatori: Operatorii aritmetici, de comparație, logici, de atribuire, ternar și pe biți din Java, cu ordinea lor de evaluare.
  • Tipuri wrapper și autoboxing: Fiecare primitiv are o clasă „înveliș” (Integer, Double, Character…); conversia automată între ele se numește autoboxing.