W3docs

Les nombres en Java

Travaillez avec les types numériques en Java — int, long, float, double — et comprenez la précision, le débordement et la classe Number.

Java distingue les nombres entiers et les nombres à virgule flottante, et dans chaque famille il existe plusieurs tailles. Choisir le bon type est important à la fois pour la justesse (précision, plage de valeurs) et la performance. Ce chapitre est un tour d'horizon ciblé des types numériques, de leurs littéraux, de leurs conversions et des pièges qui surprennent les débutants. Il suppose que vous savez déjà comment déclarer une variable et que vous avez vu l'ensemble complet des types de données primitifs.

Les primitives numériques

TypeBitsPlageStyle de littéral par défaut
byte8-128 à 127byte b = 10;
short16-32 768 à 32 767short s = 30_000;
int32-2³¹ à 2³¹-1 (≈ ±2,1 milliards)int i = 1_000_000;
long64-2⁶³ à 2⁶³-1long l = 9_000L;
float32IEEE 754 simple précision (~7 chiffres)float f = 3.14f;
double64IEEE 754 double précision (~16 chiffres)double d = 3.14;

Dans la pratique Java courante :

  • Utilisez int pour les compteurs, les index et la plupart des valeurs entières.
  • Utilisez long quand vous risquez de dépasser ~2 milliards (tailles de fichiers, millisecondes depuis l'époque, générateurs d'ID).
  • Utilisez double pour les calculs en virgule flottante.
  • Utilisez float uniquement lorsque la mémoire est limitée ou qu'une API l'exige.

Littéraux entiers

Les chiffres ordinaires sont de type int :

int answer = 42;
int million = 1_000_000;     // underscores are ignored

Le suffixe L (majuscule recommandée) pour long :

long big = 9_000_000_000L;

Le préfixe 0x pour l'hexadécimal, 0b pour le binaire, 0 pour l'octal :

int hex = 0xFF;        // 255
int bin = 0b1010;      // 10
int oct = 0755;        // 493 — be careful, easy to write by accident

(Les littéraux octaux sont une source fréquente de bogues — 0123 n'est pas 123, c'est 83. Évitez les zéros initiaux sauf si vous voulez vraiment de l'octal.)

Littéraux à virgule flottante

Les décimales ordinaires sont de type double :

double pi = 3.14159;
double e = 2.71828;

Le suffixe f pour float, d pour un double explicite (optionnel) :

float pif = 3.14f;
double pid = 3.14d;

La notation scientifique fonctionne aussi :

double avogadro = 6.022e23;
double tiny = 1.0e-9;

Conversion entre types numériques

Java effectue automatiquement une conversion élargie lorsqu'un type plus petit est affecté à un type plus grand (aucune donnée ne peut être perdue) :

int x = 7;
double promoted = x;   // 7.0 — int widens to double automatically

Dans le sens inverse, il s'agit d'un rétrécissement : la valeur peut ne pas tenir, donc Java vous oblige à écrire un cast explicite et supprime silencieusement ce qui ne rentre pas. Il s'agit d'une troncature, pas d'un arrondi :

double d = 9.99;
int i = (int) d;       // 9 — the fraction is dropped, never rounded

long big = 9_000_000_000L;
int truncated = (int) big;   // 410065408 — high bits lost, value is garbage

En raison de cela, ne rétrécissez que lorsque vous êtes certain que la valeur tient. Pour arrondir un double à l'entier le plus proche au lieu de tronquer, utilisez Math.round (voir Java Math).

Des conversions ont également lieu à l'intérieur des expressions. La division entière supprime le reste, ce qui surprend les débutants :

System.out.println(7 / 2);     // 3   — both operands are int, so int division
System.out.println(7 / 2.0);   // 3.5 — one double operand promotes the whole expression

Pour les règles complètes sur les casts explicites, consultez Java Type Casting.

Débordement

L'arithmétique entière se reboucle silencieusement autour des limites du type. Aucune exception n'est levée :

int max = Integer.MAX_VALUE;
System.out.println(max + 1);   // -2147483648 (Integer.MIN_VALUE)

Pour une arithmétique avec vérification du débordement, utilisez la famille Math.exact :

Math.addExact(Integer.MAX_VALUE, 1);   // throws ArithmeticException
Math.multiplyExact(100_000, 100_000);  // throws too

Utile lorsque la justesse prime sur la performance — calculs financiers, tailles d'allocation, etc.

Précision des nombres à virgule flottante

double et float sont au format IEEE 754 binaire — ils ne peuvent pas représenter la plupart des fractions décimales exactement :

System.out.println(0.1 + 0.2);   // 0.30000000000000004

Ne comparez jamais des valeurs en virgule flottante avec ==. Comparez avec une tolérance :

double diff = Math.abs(a - b);
if (diff < 1e-9) { /* close enough */ }

Pour les montants d'argent ou partout où vous avez besoin d'une arithmétique décimale exacte, utilisez BigDecimal :

import java.math.BigDecimal;

BigDecimal sum = new BigDecimal("0.1").add(new BigDecimal("0.2"));
System.out.println(sum);   // 0.3

Passez toujours des chaînes à new BigDecimal(...). Le constructeur double réintroduirait l'imprécision binaire.

Valeurs spéciales en virgule flottante

double possède trois valeurs qui ne sont pas des nombres ordinaires :

double posInf = Double.POSITIVE_INFINITY;
double negInf = Double.NEGATIVE_INFINITY;
double nan = Double.NaN;

System.out.println(1.0 / 0);          // Infinity
System.out.println(-1.0 / 0);         // -Infinity
System.out.println(0.0 / 0);          // NaN

System.out.println(nan == nan);       // false — NaN compares unequal to everything
System.out.println(Double.isNaN(nan)); // true

Utilisez Double.isNaN(x) pour tester NaN ; == ne fonctionnera pas.

Les classes enveloppantes

Chaque primitive a une classe enveloppante correspondante : Byte, Short, Integer, Long, Float, Double. Ces classes étendent la classe abstraite Number. Vous en avez besoin lorsque :

  • Vous utilisez des collections qui contiennent des objets : List<Integer>, Map<String, Double>.
  • Vous analysez des chaînes : Integer.parseInt("42"), Double.parseDouble("3.14").
  • Vous convertissez vers un autre type numérique via .intValue(), .doubleValue(), etc.

Java effectue automatiquement l'autoboxing entre primitives et classes enveloppantes :

List<Integer> ids = new ArrayList<>();
ids.add(42);            // autobox: int → Integer
int first = ids.get(0); // unbox: Integer → int

BigInteger et BigDecimal

Lorsque les nombres peuvent être plus grands que long ou que vous avez besoin d'une précision décimale :

import java.math.BigInteger;

BigInteger huge = new BigInteger("123456789012345678901234567890");
huge.multiply(huge);

BigDecimal price = new BigDecimal("19.95");
BigDecimal tax = price.multiply(new BigDecimal("0.07"));

Ils sont plus lents que les primitives, mais pour les cas qui en ont besoin, c'est le bon compromis.

Une démonstration

java— editable, runs on the server

Et ensuite

  • Java MathMath.abs, Math.round, Math.pow, et le reste de la boîte à outils numérique.
  • Java Operators — comment les opérateurs arithmétiques, de comparaison et bit à bit se comportent sur ces types.
  • Java Booleans — le type à deux valeurs de Java, avec beaucoup moins de détails.

Pratique

Pratique
Quel type est le plus approprié pour un montant d'argent en Java ?
Quel type est le plus approprié pour un montant d'argent en Java ?
Was this page helpful?