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 ligneimportà écrire. - Toutes ses méthodes sont
static. Vous les appelez sur le nom de la classe,Math.sqrt(25), sans jamais créer d'objetMath. La page sur les membres statiques explique ce que signifiestatic.
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éthode | Rôle | Renvoie |
|---|---|---|
Math.pow(a, b) | a à la puissance b | double |
Math.sqrt(x) | racine carrée | double |
Math.cbrt(x) | racine cubique | double |
Math.abs(x) | valeur absolue | le même type que x |
Math.max(a, b) / Math.min(a, b) | le plus grand / le plus petit des deux | le plus large des deux types |
Math.round(x) | entier le plus proche | long pour un double, int pour un float |
Math.floor(x) / Math.ceil(x) | arrondi vers le bas / vers le haut | double |
Math.random() | nombre aléatoire de 0.0 à 1.0 (exclu) | double |
Math.PI, Math.E | les constantes π et e | double |
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.roundva à l'entier le plus proche. Une valeur exactement à mi-chemin est arrondie vers le haut, vers plus l'infini, donc2.5devient3et-2.5devient-2. Elle renvoie unlongpour un argumentdouble(et unintpour unfloat).Math.floorarrondit toujours vers le bas, vers moins l'infini, et renvoie undouble.Math.ceilarrondit toujours vers le haut, vers plus l'infini, et renvoie undouble.- 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 :
Math.random() * 6donne undoublede0.0jusqu'à6.0, exclu.(int)supprime la partie décimale, ce qui donne l'une des valeurs0, 1, 2, 3, 4, 5.+ 1décale le tout en1, 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.logest le logarithme népérien ;Math.log10est le logarithme décimal.Math.floorMod(a, b)donne un reste du signe deb, ce qui est utile pour boucler dans un intervalle, comme les jours de la semaine. L'opérateur%garde le signe dea.- Les méthodes trigonométriques (
sin,cos,tan) prennent des radians. Convertissez d'abord les degrés avecMath.toRadians. Math.addExact,Math.multiplyExactet leurs équivalents lèvent uneArithmeticExceptionen 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.