Menu

La classe Math en Java : pow, sqrt, abs, round, random et plus

Comment utiliser la classe Math de Java : Math.pow, Math.sqrt, Math.abs, Math.max et Math.min, l'arrondi avec round, floor et ceil, un nombre aléatoire dans un intervalle avec Math.random, et les constantes PI et E, avec le type de retour de chacune.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Une boîte à outils de méthodes statiques

java.lang.Math est une classe remplie de fonctions mathématiques toutes prêtes : puissances, racines, valeurs absolues, arrondis, trigonométrie, logarithmes et nombres aléatoires. Deux choses la rendent facile à utiliser :

  • Elle se trouve dans java.lang, que tout fichier Java importe automatiquement. Aucune ligne import à écrire.
  • Toutes ses méthodes sont static. Vous les appelez sur le nom de la classe, Math.sqrt(25), sans jamais créer d'objet Math. La page sur les membres statiques explique ce que signifie static.

Remarquez que certains résultats s'affichent avec .0 et d'autres non. Chaque méthode de Math a un type de retour fixe, et le connaître constitue l'essentiel de ce qu'il y a à apprendre sur cette classe.

MéthodeRôleRenvoie
Math.pow(a, b)a à la puissance bdouble
Math.sqrt(x)racine carréedouble
Math.cbrt(x)racine cubiquedouble
Math.abs(x)valeur absoluele même type que x
Math.max(a, b) / Math.min(a, b)le plus grand / le plus petit des deuxle plus large des deux types
Math.round(x)entier le plus prochelong pour un double, int pour un float
Math.floor(x) / Math.ceil(x)arrondi vers le bas / vers le hautdouble
Math.random()nombre aléatoire de 0.0 à 1.0 (exclu)double
Math.PI, Math.Eles constantes π et edouble

Math.pow : les puissances

Math.pow(base, exponent) élève un nombre à une puissance. Elle prend deux paramètres double et renvoie un double, même quand vous passez des entiers :

Pour stocker le résultat dans un int, convertissez-le avec (int). Pour de petites puissances entières, le résultat double est exact, donc la conversion donne la bonne réponse. C'est avec les grands résultats que la conversion tourne mal : un double supérieur à Integer.MAX_VALUE (2 147 483 647) est converti en exactement Integer.MAX_VALUE, donc (int) Math.pow(2, 40) donne 2147483647. Convertissez en long pour les grandes puissances, et rappelez-vous qu'au-delà de 2⁵³ un double ne peut plus représenter exactement tous les entiers. La page sur la conversion de types explique ce qu'une conversion fait à la valeur.

Java n'a pas d'opérateur de puissance. 2 ^ 3 compile, mais ^ est le XOR bit à bit, et le résultat vaut 1, pas 8. C'est l'un des bugs de débutant les plus fréquents dans le code mathématique Java.

Un double de dix millions ou plus s'affiche en notation scientifique, ce qui surprend la première fois qu'on affiche une puissance de dix :

1.0E7 signifie 1,0 × 10⁷. La valeur est la même ; seule la forme affichée change. Convertissez en long, ou formatez avec String.format("%.0f", value), pour l'afficher sous forme de chiffres simples.

Math.sqrt et Math.cbrt : les racines

Math.sqrt(x) renvoie la racine carrée de x sous forme de double. Math.cbrt(x) renvoie la racine cubique.

La racine carrée d'un nombre négatif n'est pas un nombre réel, donc Math.sqrt(-4) renvoie NaN (« not a number », pas un nombre) au lieu de lever une exception. NaN se propage à travers tous les calculs qu'il touche, alors vérifiez les entrées avant de calculer une racine si des valeurs négatives sont possibles. Math.hypot(a, b) calcule directement sqrt(a*a + b*b), ce qui est une façon courante d'obtenir la distance entre deux points.

Math.abs : la valeur absolue

Math.abs(x) retire le signe. Contrairement à pow et sqrt, elle renvoie le même type que celui que vous lui donnez : un int pour un int, un double pour un double.

L'usage habituel est une différence dont seule la taille compte, pas le sens, comme la distance entre deux positions.

Math.max et Math.min

Math.max(a, b) renvoie la plus grande de deux valeurs et Math.min(a, b) la plus petite. Elles prennent exactement deux arguments. Pour trois ou plus, imbriquez les appels :

Quand les deux arguments ont des types différents, le plus étroit est d'abord élargi. Math.max(3, 7.5) compare deux valeurs double et renvoie un double. Le dernier exemple borne une valeur dans l'intervalle 0 à 100 : Math.min la plafonne à 100, Math.max l'empêche de descendre sous 0.

Arrondir : round, floor, ceil

Java a trois méthodes d'arrondi, qui diffèrent à la fois par le sens et par le type de retour :

  • Math.round va à l'entier le plus proche. Une valeur exactement à mi-chemin est arrondie vers le haut, vers plus l'infini, donc 2.5 devient 3 et -2.5 devient -2. Elle renvoie un long pour un argument double (et un int pour un float).
  • Math.floor arrondit toujours vers le bas, vers moins l'infini, et renvoie un double.
  • Math.ceil arrondit toujours vers le haut, vers plus l'infini, et renvoie un double.
  • Une conversion (int) n'est pas du tout un arrondi : elle supprime la partie décimale, ce qui fait descendre les nombres positifs et monter les nombres négatifs.

Comme Math.round(double) renvoie un long, l'affecter à un int ne compile pas sans conversion :

int n = Math.round(2.6);          // error: incompatible types: possible lossy conversion from long to int
int m = (int) Math.round(2.6);    // OK, m vaut 3
long k = Math.round(2.6);         // OK

Pour arrondir à un certain nombre de décimales, multipliez, arrondissez, puis divisez. Diviser par 100.0 (un double) plutôt que par 100 conserve les décimales :

La deuxième ligne divise un long par un int, ce qui est une division entière, donc les décimales sont perdues. Quand vous avez seulement besoin d'afficher un nombre arrondi, String.format("%.2f", value) est plus simple et ne modifie pas la valeur stockée.

Math.random : les nombres aléatoires

Math.random() renvoie un double supérieur ou égal à 0.0 et strictement inférieur à 1.0. La valeur change à chaque appel, donc la sortie des programmes de cette section change chaque fois que vous appuyez sur Run.

Pour obtenir un entier dans un intervalle, étirez cette valeur, convertissez-la, puis décalez-la. Pour un entier de min à max, bornes incluses :

int value = (int) (Math.random() * (max - min + 1)) + min;

Voici comment cela fonctionne pour un dé, où min vaut 1 et max vaut 6 :

  1. Math.random() * 6 donne un double de 0.0 jusqu'à 6.0, exclu.
  2. (int) supprime la partie décimale, ce qui donne l'une des valeurs 0, 1, 2, 3, 4, 5.
  3. + 1 décale le tout en 1, 2, 3, 4, 5, 6.

La première ligne montre cinq lancers aléatoires. La deuxième vérifie dix mille lancers et, en pratique, affiche toujours lowest: 1, highest: 6 : la formule atteint les deux bornes de l'intervalle et ne les dépasse jamais.

Les parenthèses autour de Math.random() * (max - min + 1) comptent. Une conversion s'applique à la valeur qui la suit immédiatement, donc (int) Math.random() * 6 convertit d'abord Math.random(). Cela vaut toujours 0, et 0 * 6 vaut 0, donc chaque « lancer » donne le même résultat.

Math.random() convient pour des jeux et des exercices. Pour aller plus loin, la classe java.util.Random et ThreadLocalRandom.current().nextInt(min, max + 1) (dans java.util.concurrent) renvoient directement des entiers, et Random peut recevoir une graine pour reproduire la même séquence dans des tests. Aucune de ces solutions ne convient pour des mots de passe ou des jetons de sécurité ; utilisez java.security.SecureRandom pour cela.

Math.PI et Math.E

Math.PI (π) et Math.E (le nombre d'Euler e) sont des constantes static final double :

Utilisez-les au lieu de taper 3.14. Elles sont aussi précises qu'un double le permet, et leur nom dit au lecteur de quel nombre il s'agit.

Résultats entiers et résultats double

La plupart des méthodes de Math prennent et renvoient des double. Quand vous leur passez des valeurs int, Java élargit automatiquement les arguments en double, mais le calcul que vous écrivez avant l'appel se fait toujours en int. C'est de là que viennent la plupart des mauvaises réponses :

items / perBox vaut 7 / 2, et diviser deux valeurs int supprime le reste, donc le résultat vaut 3 avant même que Math.ceil le voie. Math.ceil(3.0) vaut 3.0. Faites de l'un des opérandes un double, avec une conversion ou un littéral comme 4.0, pour que la division garde sa partie décimale. La page sur les opérateurs explique la division entière plus en détail.

La règle générale : décidez du type que vous voulez obtenir à la fin, faites la division ou la multiplication en double quand les décimales comptent, et ne reconvertissez en int ou en long qu'une seule fois, à la fin.

Autres méthodes utiles

Quelques méthodes de plus de la même classe, qui s'appellent toutes de la même façon :

  • Math.log est le logarithme népérien ; Math.log10 est le logarithme décimal.
  • Math.floorMod(a, b) donne un reste du signe de b, ce qui est utile pour boucler dans un intervalle, comme les jours de la semaine. L'opérateur % garde le signe de a.
  • Les méthodes trigonométriques (sin, cos, tan) prennent des radians. Convertissez d'abord les degrés avec Math.toRadians.
  • Math.addExact, Math.multiplyExact et leurs équivalents lèvent une ArithmeticException en cas de dépassement au lieu de revenir silencieusement à un nombre négatif.

Questions fréquentes

Comment utiliser Math.pow en Java ?

Math.pow(base, exponent) renvoie base élevé à la puissance exponent sous forme de double, donc Math.pow(2, 3) vaut 8.0. Pour stocker le résultat dans un int, convertissez-le : int n = (int) Math.pow(2, 10); donne 1024. Java n'a pas d'opérateur de puissance ^ ; ^ est le XOR bit à bit.

Comment générer un nombre aléatoire dans un intervalle avec Math.random ?

Math.random() renvoie un double compris entre 0.0 inclus et 1.0 exclu. Pour un entier de min à max inclus, utilisez (int) (Math.random() * (max - min + 1)) + min. Un lancer de dé s'écrit (int) (Math.random() * 6) + 1.

Faut-il importer la classe Math en Java ?

Non. Math se trouve dans le package java.lang, que tout fichier Java importe automatiquement. Toutes ses méthodes sont static, donc vous les appelez sur le nom de la classe, comme Math.sqrt(16), sans créer d'objet.

Pourquoi Math.round renvoie-t-il un long en Java ?

Math.round(double) renvoie un long parce qu'un double peut contenir des valeurs bien plus grandes qu'un int. Affecter le résultat à un int nécessite une conversion : int n = (int) Math.round(2.6);. Math.round(float) renvoie un int.

Quelle est la différence entre Math.floor, Math.ceil et Math.round ?

Math.floor arrondit vers le bas (2.7 devient 2.0, -2.3 devient -3.0), Math.ceil arrondit vers le haut (2.1 devient 3.0), et Math.round va à l'entier le plus proche, les moitiés allant vers le haut (2.5 devient 3). floor et ceil renvoient un double ; round renvoie un long.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER