FAQ Langage JavaConsultez toutes les FAQ
Nombre d'auteurs : 42, nombre de questions : 297, dernière mise à jour : 19 septembre 2017 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur le forum Java de http://java.developpez.com ainsi que l'expérience personnelle des auteurs.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.
Sur ce, nous vous souhaitons une bonne lecture.
- Comment représenter un nombre en Java ?
- Quelles sont les limites numériques et capacités des nombres ?
- Comment déclarer des nombres entiers ?
- Comment déclarer des nombres entiers en octal ?
- Comment déclarer des nombres entiers en hexadécimal ?
- Comment déclarer des nombres entiers en binaire ?
- Comment déclarer des nombres flottants ?
- Que sont +0.0 et -0.0 ?
- Que sont l'infini positif et l'infini négatif ?
- Qu'est-ce que NaN ?
- Qu'est-ce que la promotion numérique ?
- Comment comparer des nombres entre eux ?
- Que sont les opérateurs d'incrémentation et de décrémentation préfixes et postfixes ?
- Comment effectuer des opérations arithmétiques sur des nombres ?
- Comment effectuer des opérations bit à bit sur des nombres entiers ?
- Comment effectuer des décalages sur des nombres ?
- Comment faire des calculs de précision corrects avec des floats ou des doubles ?
- Comment arrondir un nombre ?
- Comment effectuer un tirage aléatoire ?
- Quelles API utiliser pour faire des maths ?
- Comment convertir un nombre en chaîne de caractères ?
- Comment convertir un nombre en chaîne de caractères formatée ?
- Comment convertir un nombre entier décimal en une chaîne représentant ce nombre dans une autre base ?
- Comment convertir une chaîne de caractères en nombre ?
- Comment convertir une chaîne représentant un nombre entier en base quelconque en un entier décimal ?
- Comment faire en sorte que le paramètre int de ma méthode soit modifié en retour ?
Il est possible de représenter un nombre en Java en utilisant un des types numériques primitifs suivants : byte, char, short, int, long, float et double. Ces types sont directement pris en charge par le langage en tant que type de base ; ce sont donc les types numériques que vous utiliserez le plus souvent. Par exemple :
Code Java : | Sélectionner tout |
1 2 | int a = 3; double b = 0.5; |
De plus, chacun de ces types primitifs dispose d'une classe wrapper équivalente qui permet de les manipuler comme des objets : java.lang.Byte, java.lang.Character, java.lang.Short, java.lang.Integer, java.lang.Long, java.lang.Float, java.lang.Double. Toutes ces classes, hormis la classe Character, héritent de la classe java.lang.Number. Par exemple :
Code Java : | Sélectionner tout |
1 2 | Integer a = new Integer(2); Double b = new Double(0.5); |
Ou encore grâce à l'auto-boxing :
Code Java : | Sélectionner tout |
1 2 | Integer a = 2; Double b = 0.5; |
Il existe de plus des classes permettant d'effectuer des calculs en faisant abstraction de la précision et de la capacité des types de base : java.math.BigInteger et java.math.BigDecimal qui héritent toutes les deux également de la classe Number.
L'API dispose également d'autres classes dédiées aux valeurs numériques qui sont utilisées dans des domaines très particuliers tels que java.util.concurrent.atomic.AtomicInteger, mais vous les utiliserez plus rarement.
Nombres entiers
- byte (classe wrapper java.lang.Byte) - des octets : des nombres entiers signés sur 8 bits ;
- char (classe wrapper java.lang.Character) - des caractères : des symboles pour écrire du texte, mais également des nombres entiers non signés sur 16 bits ;
- short (classe wrapper java.lang.Short) - des entiers courts : des nombres entiers signés sur 16 bits ;
- int (classe wrapper java.lang.Integer) - des entiers normaux ou mots : des nombres entiers signés sur 32 bits.
- long (classe wrapper java.lang.Long) - des entiers longs : des nombres entiers signés sur 64 bits.
- java.math.BigInteger - des nombres entiers signés à précision arbitraire.
Nombres à virgule flottante
- float (classe wrapper java.lang.Float) - des nombres flottants simple précision : des nombres à virgule flottante signés sur 32 bits ;
- double (classe wrapper java.lang.Double) - des nombres flottants double précision : des nombres à virgule flottante signés sur 64 bits ;
- java.math.BigDecimal - des nombres à virgule flottante signés à précision arbitraire.
Il n'existe pas dans l'API de base d’entité qui permet de manipuler des nombres complexes.
Les limites et capacités des différents types de nombres sont définies dans les spécifications du langage Java. Ainsi, ces spécifications demeurent identiques que vous ayez une JVM 32 bitsou 64 bits. Par exemple, contrairement à d'autres langages ou compilateur, en Java un int fait toujours 32 bits et définit toujours un nombre entier signé.
Nombres entiers
Au niveau de la capacité : byte < char et short < int < long.
Type | Wrapper | Capacité | Signé | Valeur minimale | Valeur maximale | Constante minimale | Constante maximale |
byte | java.lang.Byte | 8 bits | oui | -128 (-27) | +127 (27-1) | Byte.MIN_VALUE | Byte.MAX_VALUE |
char | java.lang.Character | 16 bits | non | 0 (0x0000) | 65535 (0xFFFF) | Character.MIN_VALUE | Character.MAX_VALUE |
short | java.lang.Short | 16 bits | oui | -32768 (-215) | +32767 (215-1) | Short.MIN_VALUE | Short.MAX_VALUE |
int | java.lang.Integer | 32 bits | oui | -231 | 231-1 | Integer.MIN_VALUE | Integer.MAX_VALUE |
long | java.lang.Long | 64 bits | oui | -263 | 263-1 | Long.MIN_VALUE | Long.MAX_VALUE |
Au niveau de la capacité : float < double.
Type | Wrapper | Capacité | Signé | Valeur minimale positive | Valeur maximale positive | Constante minimale positive | Constante maximale positive |
float | java.lang.Float | 32 bits | oui | 2-149 | (2-2-23)·2127 | Float.MIN_VALUE | Float.MAX_VALUE |
double | java.lang.Double | 64 bits | oui | 2-1074 | (2-2-52)·21023 | Double.MIN_VALUE | Double.MAX_VALUE |
- Primitive Types and Values dans les spécifications de Java.
De manière générale, il vous suffit d’écrire une variable du type approprié et de lui affecter une valeur numérique.
Le compilateur acceptera n'importe quelle valeur tant que cette dernière entre dans la limite des valeurs supportées par ce type. Une erreur sera générée si la valeur dépasse la capacité du type utilisé et un cast sera requis pour être capable de compiler ; la valeur ainsi obtenue sera tronquée pour pouvoir être stockée dans le type choisi.
Il est également possible d'utiliser le caractère _ pour effectuer des groupements de chiffres.
Octets (byte)
Code Java : | Sélectionner tout |
1 2 3 4 5 | byte b0 = 1; byte b1 = -128; byte b2 = 127; byte b3 = 1_00; // Fonctionne sans problème. byte b4 = 500; // Erreur, dépassement de capacité. |
Entiers courts (short)
Code Java : | Sélectionner tout |
1 2 3 4 5 6 | short s0 = 1; short s1 = -32768; short s2 = 32767; short s3 = 32_767; // Fonctionne sans problème. short s4 = 3_27_67; // Fonctionne sans problème. short s5 = 1000000; // Erreur, dépassement de capacité. |
Entiers normaux ou mots (int)
Code Java : | Sélectionner tout |
1 2 3 4 | int s0 = 1; int s1 = -1000000; int s2 = 1000000; int s3 = 1_000_000; // Fonctionne sans problème. |
Entiers longs (long)
Lorsque le nombre écrit dépasse la capacité d'un nombre entier, il vous suffit de le suffixer par la lettre L minuscule ou majuscule (l ou L) pour forcer le compilateur à comprendre qu'il s'agit d'un nombre entier long.
Code Java : | Sélectionner tout |
1 2 3 4 5 6 | long l0 = 1; long l2 = 1000000; // Inférieur à la capacité d'un entier. long l1 = -10000000000l; // Supérieur à la capacité d'un entier. long l3 = 10000000000l; // Supérieur à la capacité d'un entier. long l4 = 10000000000L; // Supérieur à la capacité d'un entier. long l5 = 10_000_000_000L; // Fonctionne sans problème. |
Il est possible de déclarer nativement des nombres entiers en octal directement dans le code source Java. La valeur octale du nombre doit être préfixée par la valeur 0 et ne peut contenir que les caractères [0-7] et le caractère - pour les valeurs négatives.
Le compilateur acceptera n'importe quelle valeur tant que cette dernière entre dans la limite des valeurs supportées par ce type. Une erreur sera générée si la valeur dépasse la capacité du type utilisé et un cast sera requis pour être capable de compiler ; la valeur ainsi obtenue sera tronquée pour pouvoir être stockée dans le type choisi.
Par exemple, il est tout à fait possible d’écrire :
Code Java : | Sélectionner tout |
1 2 3 | byte unByte = 010; // UnByte vaut 8. short unShort = 063675; int unEntier = 06367512354; |
Il est possible de déclarer des entiers longs (long) en binaire en suffixant la déclaration avec le marqueur habituel (l ou L). Par exemple :
Code Java : | Sélectionner tout |
long unLong = 06367512354523L;
Il est également possible d'utiliser le caractère _ pour effectuer des groupements de chiffres. Par exemple :
Code Java : | Sélectionner tout |
1 2 3 4 | byte unByte = 0_1_0; short unShort = 06_36_75; int unEntier = 0636_751_2354; long unLong = 06_3675_1235_4523L; |
Il est possible de déclarer nativement des nombres entiers en hexadécimal directement dans le code source Java. La valeur binaire du nombre doit être préfixée par la valeur 0x et ne peut contenir que les caractères [0-9A-Fa-f] et le caractère - pour les valeurs négatives.
Le compilateur acceptera n'importe quelle valeur tant que cette dernière entre dans la limite des valeurs supportées par ce type. Une erreur sera générée si la valeur dépasse la capacité du type utilisé et un cast sera requis pour être capable de compiler ; la valeur ainsi obtenue sera tronquée pour pouvoir être stockée dans le type choisi.
Par exemple, il est tout à fait possible d’écrire :
Code Java : | Sélectionner tout |
1 2 3 | byte unByte = 0x1A; short unShort = 0xFF; int unEntier = 0xADAFF01; |
Il est possible de déclarer des entiers longs (long) en binaire en suffixant la déclaration avec le marqueur habituel (l ou L). Par exemple :
Code Java : | Sélectionner tout |
long unLong = 0xFFFFFFFFFFL;
Il est également possible d'utiliser le caractère _ pour effectuer des groupements de bits. Par exemple :
Code Java : | Sélectionner tout |
1 2 3 4 | byte unByte = 0x1_A; short unShort = 0xF_F; int unEntier = 0xAD_AFF01; long unLong = 0xFF_FFFF_FFFFL; |
Depuis le JDK7, il est possible de déclarer nativement des nombres entiers en binaire directement dans le code source Java. La valeur binaire du nombre doit être préfixée par la valeur 0b et ne peut contenir que les caractères [01] et le caractère - pour les valeurs négatives.
Note : en Java, les nombres binaires sont au format big endian.
Le compilateur acceptera n'importe quelle valeur tant que cette dernière entre dans la limite des valeurs supportées par ce type. Une erreur sera générée si la valeur dépasse la capacité du type utilisé et un cast sera requis pour être capable de compiler ; la valeur ainsi obtenue sera tronquée pour pouvoir être stockée dans le type choisi.
Par exemple, il est tout à fait possible d’écrire :
Code Java : | Sélectionner tout |
1 2 3 | byte unByte = 0b00100001; short unShort = 0b10100001010001; int unEntier = 0b10101010; // unEntier vaut 170. |
Il est possible de déclarer des entiers longs (long) en binaire en suffixant la déclaration avec le marqueur habituel (l ou L). Par exemple :
Code Java : | Sélectionner tout |
long unLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;
Il est également possible d'utiliser le caractère _ pour effectuer des groupements de bits. Par exemple :
Code Java : | Sélectionner tout |
1 2 3 4 | byte unByte = 0b00_10_00_01; short unShort = 0b1010000_1010001; int unEntier = 0b1010_1010; // unEntier vaut 170. long unLong = 0b10100001_01000101_10100001_01000101_10100001_01000101_10100001_01000101L; |
Autre méthode
Pour les JVM plus anciennes, il reste possible de parser une chaine de caractères représentant un nombre binaire en invoquant la méthode adéquate parsexxx() de la classe wrapper ciblée et en passant la valeur 2 pour le paramètre radix. Par exemple, pour un entier :
Code Java : | Sélectionner tout |
int decimal = Integer.parseInt("1001", 2); // decimal vaut 9.
Cette solution est toutefois sujette aux créations d'exceptions habituelles des méthodes parsexxx() et aucune vérification de dépassement de capacité ne peut être effectuée par l'IDE ou le compilateur puisque la valeur sera parsée durant l’exécution.
De manière générale, il vous suffit d’écrire une variable du type appropriée et de lui affecter une valeur numérique. En Java, l’arithmétique des nombres flottants suit le standard IEEE 754.
Attention : la notation des nombres se fait en suivant la syntaxe anglo-saxonne. Ici, c'est donc le caractère point (.) et non pas la virgule qui sert de séparateur entre la partie entière et partie flottante du nombre.
Le compilateur acceptera n'importe quelle valeur tant que cette dernière entre dans la limite des valeurs supportées par ce type. Une erreur sera générée si la valeur dépasse la capacité du type utilisé et un cast sera requis pour être capable de compiler ; la valeur ainsi obtenue sera approximée pour pouvoir être stockée dans le type choisi.
Il est également possible d'utiliser le caractère _ pour effectuer des groupements de chiffres. Ces groupements peuvent s'effectuer avant ou après le point qui sert de séparation entre la partie entière et partie flottante.
Simple précision (float)
Lorsque le nombre est écrit en simple précision, il peut être nécessaire de le suffixer par la lettre F minuscule ou majuscule (f ou F) pour forcer le compilateur à comprendre qu'il s'agit d'un nombre flottant en simple précision.
Code Java : | Sélectionner tout |
1 2 3 4 5 6 | float f0 = 0; float f1 = -5.25f; float f2 = 5.25f; float f3 = 377.845f; float f4 = 377.845F; float f5 = 84_377.845_875F |
Double précision (double)
Lorsque le nombre est écrit en double précision, il est possible, mais pas obligatoire, de le suffixer par la lettre D minuscule ou majuscule (d ou D).
Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 | double d0 = 0; double d1 = -5.25; double d2 = 5.25; double d3 = 377.845d; double d4 = 377.845D; double d5 = 84_377.845_875; double d6 = 84_377.845_875D; |
Le standard IEEE 754 définit l’arithmétique des nombres flottants. Cette norme permet l’existence de deux valeurs pour le nombre 0 : le +0.0 (zéro positif ou positive zero) et le -0.0 (zéro négatif ou negative zero). Par convention, certains opérateurs considèrent ces valeurs comme égales tandis que d'autres peuvent tenir compte du signe. La représentation binaire exacte de 0.0 et -0.0 varie suivant le type utilisé.
Par exemple :
Code Java : | Sélectionner tout |
1 2 3 4 5 6 | float a = 0f; // 0f s’écrit 00000000000000000000000000000000 en binaire. float b = -0f; // -0f s’écrit 10000000000000000000000000000000 en binaire. boolean c = a == b; // c contient true. boolean d = a > b; // d contient false. double e = 1 / a; // e contient Infinity. double f = 1 / b; // f contient -Infinity. |
Conventions
- - (0.0) a pour résultat -0.0.
- - (-0.0) a pour résultat 0.0.
- 0.0 == -0.0, 0.0 <= -0.0 et 0.0 >= -0.0 retournent true tandis que 0.0 != -0.0 retourne false. Cependant, les méthodes des bibliothèques numériques (ex. : Math.min()) peuvent valider le test -0.0 < 0.0. De même, la comparaison d'instances de classes wrapper par la méthode equals() échoue, car cette dernière teste la représentation binaire des valeurs.
Par exemple :Code Java : Sélectionner tout 1
2
3
4
5Double a = 0.0; Double b = -0.0; boolean c = a.doubleValue() == b.doubleValue()); // c contient true. boolean d = a == b; // d contient false : teste les références de a et de b. boolean e = a.equals(b); // e contient false : teste la représentation binaire des valeurs.
Dans le standard IEEE 754, deux valeurs sont censées représenter les limites extérieures de la plage de valeurs qu'il est possible de représenter par des nombres à virgule flottante : +∞ (infini positif ou positive infinity) et −∞ (infini négatif ou negative infinity). Ces nombres sont représentés par des constantes spéciales POSITIVE_INFINITY NEGATIVE_INFINITY définies dans les classes Float et Double. Ces valeurs peuvent être retournées en résultat de certaines opérations arithmétiques. La représentation binaire exacte de +∞ et −∞ varie suivant le type utilisé.
Par exemple :
Code Java : | Sélectionner tout |
1 2 | double a = 1 / 0.0; // a contient Infinity. double b = 1 / -0.0; // b contient -Infinity. |
Il est possible de tester si une valeur est « infinie » (dispose d'une magnitude infiniment large) en invoquant la méthode isInfinite() de la classe wrapper correspondante. A contrario, la méthode isFinite() renvoie le résultat opposé.
Conventions
- - Positive Infinity retourne Negative Infinity.
- - Negative Infinity retourne Positive Infinity
- Positive Infinity + Positive Infinity retourne Positive Infinity.
- Negative Infinity + Negative Infinity retourne Negative Infinity.
- x + y retourne Infinity si x ou y vaut Infinity ou si la valeur de la somme est trop grande (le signe de l’infinité dépend du signe de la variable).
- x - y retourne Infinity si x ou y vaut Infinity ou si la valeur de la différence est trop grande (le signe de l’infinité dépend du signe de la variable).
- x * Infinity (x est un nombre quelconque, hors 0) retourne Infinity (le signe de l’infinité dépend du signe de la variable).
- x / y peut retourner Infinity si le quotient de la division est trop grand (le signe de l’infinité dépend du signe de la variable).
- Infinity / y retourne Infinity (le signe de l’infinité dépend du signe de la variable).
- x / Infinity retourne 0 (le signe du zéro dépend du signe de la variable).
- f / 0F et f / 0D (f est un nombre flottant quelconque, hors 0) retournent Infinity (le signe de l’infinité dépend du signe de la variable) ; tandis que n / 0 et n / 0L (n est un entier quelconque) génèrent une exception de type java.lang.ArithmeticException contenant le message « / by zero ».
- positive Infinity toujours plus grand que n'importe quelle valeur flottante.
- Negative Infinity toujours plus petit que n'importe quelle valeur flottante.
- Positive Infinity est toujours égal à lui-même et toujours différent de toute autre valeur.
- Negative Infinity est toujours égal à lui-même et toujours différent de toute autre valeur.
Dans le standard IEEE 754, la valeur NaN (Not a Number, soit littéralement « pas un nombre ») est une valeur spéciale des types float et double destinée à représenter la valeur résultat d'une opération arithmétique non valide, par exemple 0F/0F. La représentation binaire exacte de NaN varie suivant le type utilisé.
Toute opération arithmétique dans laquelle au moins un des deux opérandes est à la valeur NaN retournera la valeur NaN.
Étant donné que NaN est une valeur particulière, il convient donc de la traiter avec précaution. Ainsi, il ne faut pas utiliser les opérateurs == (égalité) ou != (différence) pour vérifier si une variable ou une constante est à la valeur NaN. En effet, le test d’égalité sur NaN retourne tout le temps la valeur false, même en testant NaN à lui-même ; respectivement, le test de différence retourne tout le temps true. De la même manière, tous les opérateurs de comparaison entre deux valeurs (ex. : < (plus petit que), > (plus grand que), etc.) retourneront tout le temps la valeur false si au moins un des deux opérandes est à la valeur NaN.
Par exemple :
Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | float a = Float.NaN; float b = 5f; System.out.println(a == Float.NaN); // Imprime false. System.out.println(b == Float.NaN); // Imprime false. System.out.println(a != Float.NaN); // Imprime true. System.out.println(b != Float.NaN); // Imprime true. System.out.println(a < Float.NaN); // Imprime false. System.out.println(b < Float.NaN); // Imprime false. System.out.println(a > Float.NaN); // Imprime false. System.out.println(b > Float.NaN); // Imprime false. |
Pour tester si une variable est à la valeur NaN, il faut utiliser la méthode isNaN() des classes Double et Float.
Code Java : | Sélectionner tout |
1 2 3 4 | float a = Float.NaN; float b = 5f; System.out.println(Float.isNaN(a)); // Imprime true. System.out.println(Float.isNaN(b)); // Imprime false. |
Conventions
- -NaN retourne NaN ;
- x + y retourne NaN si x ou y vaut NaN.
- x - y retourne NaN si x ou y vaut NaN.
- x * y retourne NaN si x ou y vaut NaN.
- x / y retourne NaN si x ou y vaut NaN.
- x % y retourne NaN si x ou y vaut NaN.
- Positive Infinity + Negative Infinity retourne NaN.
- Positive Infinity - Negative Infinity retourne NaN.
- 0F * Infinity et 0D * Infinity retournent NaN.
- 0 / 0F et 0 / 0D retournent NaN.
- Infinity / Infinity retourne NaN.
- Infinity % x retourne NaN.
- x % 0F et x % 0D retournent NaN.
- x == y, x != y, x < y, x <= y, x > y et x >= y retournent false si x ou y vaut NaN.
La promotion numérique (numeric promotion) est un mécanisme par lequel certains opérateurs Java peuvent modifier les opérandes qui leur sont fournis de manière à pouvoir effectuer le calcul. Il existe deux cas de figure :
Promotion numérique unaire
La promotion numérique unaire (unary numeric promotion) peut s'effectuer sur les opérateurs qui prennent un seul et unique opérande. Elle applique les règles suivantes :
- si l’opérande est une référence des types wrapper Byte, Short, Character ou Integer, il peut être soumis à l'auto-unboxing. La valeur résultat peut être convertie en int ou conserver son type primitif (si c'est déjà int) ;
- sinon, si l’opérande est une référence des types wrapper Long, Float ou Double, il peut être soumis à l'auto-unboxing ;
- sinon, si l’opérande est de type byte short ou char ou Double, il est converti en int ;
- sinon, il conserve son type.
Promotion numérique binaire
La promotion numérique binaire (binary numeric promotion) peut s'effectuer sur les opérateurs qui prennent deux opérandes. Elle applique les règles suivantes :
- si les opérandes sont des références (les types wrapper des classes numériques), ils peuvent être soumis à l'auto-unboxing ;
- les valeurs peuvent être « agrandies dans un type conteneur plus grand » suivant les règles suivantes :
- si un des opérandes est de type double, l'autre est converti en double,
- sinon, si un des opérandes est de type float, l'autre est converti en float,
- sinon, si un des opérandes est de type long, l'autre est converti en long,
- sinon, les deux opérandes sont convertis en int ;
- si besoin, les règles de conversion régissant la précision des calculs des types flottants s'appliquent alors.
Pour comparer des nombres entre eux, vous devez utiliser les opérateurs conditionnels == (« égalité » ou equals to) ou != (« différence » ou different from ou is not). Vous pouvez également utiliser les opérateurs < (« plus petit que » ou lesser than), <= (« plus petit ou égal à » ou lesser or equal than), > (« plus grand que » ou bigger than) et >= (« plus grand ou égal à » ou bigger or equal than). Tous ces opérateurs produisent des résultats de type boolean. Le mécanisme de la promotion numérique binaire s'applique sur ces opérateurs.
Par exemple :
Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 | int a = 3; int b = 9; boolean c = a == b; // c vaut false. boolean d = a != b; // d vaut true. boolean e = a < b; // e vaut true. boolean f = a <= b; // f vaut true. boolean g = a > b; // g vaut false. boolean h = a >= b; // h vaut false. |
Il existe quatre opérateurs permettant d’incrémenter et de décrémenter rapidement les valeurs de variables numériques : le ++ préfixe (« incrément préfixe » ou Prefix Increment) et le ++ postfixe (« incrément postfixe » ou Postfix Increment), le -- préfixe (« décrément préfixe » Prefix Decrement) et le -- postfixe (« décrément postfixe » ou Postfix Decrement). La promotion numérique binaire s'applique à la fois sur l’opérande explicite de ces opérateurs (la valeur à incrémenter ou décrémenter) ainsi que sur son opérande implicite (l’incrément ou le décrément qui vaut tout le temps 1).
Opérateurs préfixes
Les opérateurs préfixes précédent la variable à incrémenter ou décrémenter de 1. Avec ces opérateurs, l’opération d’incrémentation ou de décrémentation est appliquée à la variable ; puis, l'expression retourne la nouvelle valeur de la variable.
Par exemple :
Code Java : | Sélectionner tout |
1 2 3 | int a = 0; // Valeur initiale. int b = ++a; // a et b valent 1. int c = --a; // a et c valent 0. |
Ici, par exemple, immédiatement après avoir fait b = ++a;, les variables a et b ont exactement la même valeur.
Opérateurs postfixes
Les opérateurs postfixes suivent la variable à incrémenter ou décrémenter de 1. Avec ces opérateurs, la valeur originelle de la variable devient la valeur de retour de l'expression ; puis, l’opération d’incrémentation ou de décrément est appliquée à la variable.
Par exemple :
Code Java : | Sélectionner tout |
1 2 3 | int a = 0; // Valeur initiale. int b = a++; // a vaut 1 mais b vaut 0. int c = a--; // a vaut 0 mais c vaut 1. |
Ici, par exemple, immédiatement après avoir fait b = a++;, la variable a a été incrémentée de 1 tandis que la variable b contient sa valeur initiale 0.
Pour effectuer des opérations arithmétiques sur des nombres, vous devez utiliser les opérateurs arithmétiques + (« plus » ou « addition » ou added to), - (« moins » ou « soustraction » ou subtracted from), * (« fois » ou « multiplication par » ou multiplied y), / (« divisé par » ou « division par » ou divided by) ou % (« reste de la division » ou remainder). Le mécanisme de la promotion numérique binaire s'applique sur ces opérateurs.
Par exemple :
Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | int a = 3; int b = 9; int c = a + b; // c vaut 12. int d = a - b; // d vaut -6. int e = a * b; // e vaut 27. int f = a / b; // f vaut 0 (division entière). float g = a / (float)b; // g vaut 0.333333...f (division flottante). int h = a % b; // h vaut 3. float i = a % (float) b; // i vaut 3.0f. |
Note : contrairement à d'autres langages, l’opérateur % (reste de la division) fonctionne également avec des valeurs non entières.
Les opérateurs d'affectation correspondants sont :
+ (addition) | - (soustraction) | * (multiplication) | / (division) | % (reste de la division) |
+= | -= | *= | /= | %= |
Pour effectuer des opérations bit à bit (bitwise) sur des nombres entiers (byte, char, short, int et long), vous devez utiliser les opérateurs & (« et bit à bit » ou bitwise and), | (« ou inclusif bit à bit » ou bitwise inclusive or), ^ (« ou exclusif bit à bit » ou bitwise exclusive or ou xor). Il est également possible d'utiliser l’opérateur à un seul opérande ~ (« complément bit à bit » ou bitwise complement) qui remplace le contenu binaire d'un nombre par son complément. Ces opérateurs peuvent s'appliquer à des valeurs entières provenant de constantes ou de variables et ils produisent des résultats de type int ou long en fonction du type des opérandes. Le mécanisme de la promotion numérique binaire s'applique sur ces opérateurs.
Par exemple :
Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 | int a = 3; // 3 s’écrit 0011 en binaire. int b = 9; // 9 s’écrit 1001 en binaire. int c = a & b; // c vaut 1 donc 0001 en binaire. int d = a | b; // d vaut 11 donc 1011 en binaire. int e = a ^ b; // e vaut 10 donc 1010 en binaire. int f = ~a; // c vaut -4 donc 11111111111111111111111111111100 en binaire. int g = ~b; // d vaut -10 donc 11111111111111111111111111110110 en binaire. |
Ce qui nous donne :
Code Console : | Sélectionner tout |
1 2 3 4 5 | 3 & 9 ↔ 0000000000000000000000000000011 & 0000000000000000000000000001001 ↔ 00000000000000000000000000000001 ↔ 1 3 | 9 ↔ 0000000000000000000000000000011 | 0000000000000000000000000001001 ↔ 00000000000000000000000000001011 ↔ 11 3 ^ 9 ↔ 0000000000000000000000000000011 ^ 0000000000000000000000000001001 ↔ 00000000000000000000000000001010 ↔ 10 ~ 3 = ~ 0000000000000000000000000000011 ↔ 11111111111111111111111111111100 ↔ -4 ~ 9 = ~ 0000000000000000000000000001001 ↔ 11111111111111111111111111110110 ↔ -10 |
Note : il est assez facile de calculer la valeur décimale du complément binaire d'un entier ; en effet : ~x = (-x)-1.
Les opérateurs d'affectation correspondants sont :
& (et bit à bit) | | (ou inclusif bit à bit) | ^ (ou exclusif bit à bit) | ~ (complément bit à bit) |
&= | |= | ^= | pas d’équivalent |
a | b | a & b (et bit à bit) | a | b (ou inclusif bit à bit) | a ^ b (ou exclusif bit à bit) | ~ a (complément bit à bit) |
0 | 0 | 0 | 0 | 0 | 1 |
0 | 1 | 0 | 1 | 1 | 1 |
1 | 0 | 0 | 1 | 1 | 0 |
1 | 1 | 1 | 1 | 0 | 0 |
Pour effectuer des décalages sur des nombres, vous devez utiliser les opérateurs << (« décalage à gauche » ou left shift), >> (« décalage à droite avec préservation du signe » ou signed right shift) et >>> (« décalage à droite sans préservation du signe » ou unsigned right shift). L’opérande de gauche est la valeur sur laquelle on opère le décalage tandis que l’opérande de droite est le nombre de bits qui doivent être décalés vers un côté ou l'autre en fonction de la nature de l’opérateur. Le mécanisme de la promotion numérique unaire s'applique sur chaque opérande de ces opérateurs (bien qu'il s'agisse d’opérateurs acceptant deux opérandes).
Par exemple :
Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 | int a = 3; // 3 s’écrit 0011 en binaire. int b = -9; // -3 s’écrit 11111111111111111111111111110111 en binaire. int c = a << 1; // c vaut 6 donc 0110 en binaire. int d = b << 1; // d vaut -18 donc 11111111111111111111111111101110 en binaire. int e = a >> 1; // e vaut 1 donc 0001 en binaire. int f = b >> 1; // f vaut -5 donc 11111111111111111111111111111011 en binaire. int g = a >>> 1; // g vaut 1 donc 0001 en binaire. int h = b >>> 1; // h vaut 2147483643 donc 01111111111111111111111111111011 en binaire. |
La différence entre >> (décalage à droite avec préservation du signe) et >>> (décalage à droite sans préservation du signe) est que >> préserve la valeur du bit le plus à gauche lors du décalage, préservant ainsi le signe de la valeur (ce bit a pour valeur 0 quand le nombre est positif et 1 quand le nombre est négatif).
Ce qui nous donne :
Code Console : | Sélectionner tout |
1 2 3 4 5 6 | 3 << 1 ↔ 00000000000000000000000000000011 << 1 ↔ 00000000000000000000000000000110 ↔ 6 3 >> 1 ↔ 00000000000000000000000000000011 >> 1 ↔ 00000000000000000000000000000001 ↔ 1 3 >>> 1 ↔ 00000000000000000000000000000011 >>> 1 ↔ 00000000000000000000000000000001 ↔ 1 -9 << 1 ↔ 11111111111111111111111111110111 << 1 ↔ 11111111111111111111111111101110 ↔ -18 -9 >> 1 ↔ 11111111111111111111111111110111 >> 1 ↔ 11111111111111111111111111111011 ↔ -5 -9 >>> 1 ↔ 11111111111111111111111111110111 >>> 1 ↔ 01111111111111111111111111111011 ↔ 2147483643 |
Les opérateurs d'affectation correspondants sont :
<< (décalage à gauche) | >> (décalage à droite avec préservation du signe) | >>> (décalage à droite sans préservation du signe) |
<<= | >>= | >>>= |
Si vous essayez ceci :
Code Java : | Sélectionner tout |
System.out.println(1.3-1.2);
Vous obtenez : 0.10000000000000009 au lieu de 0.1, comme indiqué sur votre calculatrice.
En fait, il est impossible de représenter exactement 0.1 ou n'importe quelle puissance négative de 10 au moyen d'un float ou d'un double. La meilleure solution pour résoudre ce problème est d'utiliser la classe java.math.BigDecimal.
On l'utilise par exemple comme ceci :
Code Java : | Sélectionner tout |
1 2 3 | BigDecimal bd1 = new BigDecimal("1.3"); BigDecimal bd2 = new BigDecimal("1.2"); System.out.println(bd1.substract(bd2)); |
Attention, les chiffres que vous voulez représenter doivent être passés comme des String dans le constructeur.
Arrondir un réel en entier :
Il suffit d'utiliser la méthode Math.floor() pour arrondir un réel à l'entier inférieur le plus proche :
Code Java : | Sélectionner tout |
double a = Math.floor(1.99); // 1.0
À l'inverse, la méthode Math.ceil() permet arrondir un réel à l'entier supérieur le plus proche :
Code Java : | Sélectionner tout |
double a = Math.ceil(1.01); // 2.0
Si l'on souhaite respecter la règle standard de l'arrondi, en utilisant l'entier supérieur ou inférieur le plus proche selon la valeur de la partie décimale, il suffit d'ajouter 0.5 à la valeur passée à Math.floor() :
Code Java : | Sélectionner tout |
double a = Math.floor(1.99+0.5); // 2.0
Code Java : | Sélectionner tout |
double a = Math.floor(1.49+0.5); // 1.0
- Si la valeur de la partie décimale est inférieure à 0.5, la valeur sera arrondie à l'entier inférieur.
- Si la valeur la partie décimale est supérieur ou égale à 0.5, la valeur sera arrondie à l'entier supérieur.
Attention : on pourrait également utiliser un cast vers les types int ou long pour « perdre » la partie décimale, mais cela peut poser des problèmes avec des grandes valeurs, car les cast peuvent conduire à une perte d'information par troncature.
Arrondir un réel à « n » décimales :
On peut également faire un arrondi à « n » décimales en utilisant le code suivant :
Code Java : | Sélectionner tout |
1 2 3 4 5 | double a = 1.6666666; // Arrondir la valeur a 10^-2 a *= 100.0; a = Math.floor(a+0.5); a /= 100.0; // 1.67 |
Pour simplifier, on peut utiliser directement cette méthode
Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | /** * Arrondi d'un double avec n éléments après la virgule. * @param a La valeur à convertir. * @param n Le nombre de décimales à conserver. * @return La valeur arrondie à n décimales. */ public static double floor(double a, int n) { double p = Math.pow(10.0, n); return Math.floor((a*p)+0.5) / p; } |
Qui s'utilise de la manière suivante :
Code java : | Sélectionner tout |
double a = floor(1.6666666, 2); // 1.67
Mais attention toutefois, on peut obtenir un résultat incorrect lorsqu'on s'approche de la limite maximum des doubles (1e308 quand même). Pour des résultats plus précis, on pourra se tourner vers la classe BigDecimal et ses méthodes setScale().
Arrondir pour afficher :
En revanche, si le résultat est destiné à une conversion en chaîne de caractères, il est préférable de se tourner vers la classe java.text.DecimalFormat.
Pour effectuer un tirage aléatoire, il faut utiliser la classe java.util.Random. Cette classe va nous permettre d'effectuer des générations de nombre pseudoaléatoire.
On peut tirer des valeurs de différents types : boolean, byte, double, float, int et long. Tout cela au moyen des méthodes nextXXX() de la classe Random.
Une particularité avec un tirage d'un entier (int) est le fait que l'on puisse configurer la séquence sur laquelle le nombre va être tiré. On peut en effet passer un paramètre à la méthode nextInt() qui sera le nombre maximum à tirer, le nombre minimal étant zéro.
Code Java : | Sélectionner tout |
1 2 3 4 | Random random = new Random(); int pseudoRandomNumber = random.nextInt(); //Un nombre aléatoire int pseudoRandomNumberTwo = random.nextInt(25); //Un nombre aléatoire entre 0 et 25. |
Pour tout connaître de la génération de nombres aléatoires, il est conseillé de consulter l'excellent tutoriel de Hugo Etiévant : Génération de variables aléatoires uniformes, normales et exponentielles avec l'API Random de Java .
Voici la description de différents « outils » pouvant vous permettre de faire des calculs mathématiques. Les deux premiers sont des classes faisant partie du JDK standard, le dernier est une API du projet Jakarta Commons.
java.lang.Math
La classe Math contient un ensemble de méthodes statiques permettant de faire des opérations numériques basiques (logarithmes, exponentielles ou fonctions trigonométriques). Contrairement à la classe StrictMath, les différentes implémentations d'une même méthode ne donnent pas le même résultat « bit à bit ». On peut quand même noter que, en général, les implémentations des méthodes de la classe Math font appel aux méthodes de StrictMath. Si la précision n'est pas le critère primordial, vous pouvez préférer Math à StrictMath pour des raisons de performance.
java.lang.StrictMath
Les méthodes de StrictMath sont les mêmes que celles de Math, à la différence que les résultats obtenus sont les mêmes que ceux produits par la version 5.3 de la bibliothèque FDLIBM (Freely Distributable Math Library).
Math 1.0 (Jakarta Commons)
Cette API (disponible sur http://commons.apache.org/proper/commons-math/) met à la disposition du développeur Java un plus grand nombre d'algorithmes mathématiques et statistiques.
Il en existe bien d'autres, plus d'informations sur la page API de Développez.
- java.lang.Math ;
- java.lang.StrictMath ;
- Guide utilisateur de l'API Commons ;
- page API de Développez.
Methode toString(valeur)
La conversion d'un nombre en chaîne de caractères est assurée par les différentes classes de gestion des types de base de Java : java.lang.Integer, java.lang.Double, java.lang.Float, java.lang.Long, java.lang.Byte.
Par exemple :
Code Java : | Sélectionner tout |
1 2 3 4 | String chaine = Integer.toString(monInt); String chaine = Long.toString(monLong); String chaine = Byte.toString(monByte); // etc. |
Il est également possible d'invoquer l'une des variantes de la méthode publique statique valueOf() de la classe String.
La classe java.text.DecimalFormat permet de formater une valeur numérique dans le format de son choix en utilisant un pattern dont les symboles principaux sont les suivants :
- 0 - permet de représenter un chiffre qui devra obligatoirement être présent, même s'il s'agit d'un zéro inutile ;
- # - permet de représenter un chiffre en ignorant les zéros inutiles ;
- . (le point) - permet de représenter le séparateur de la partie décimale ;
- , (la virgule) - permet de représenter le séparateur des groupes (milliers, millions, etc.).
Vous pouvez vous reporter à la documentation de la classe DecimalFormat pour obtenir la liste complète de tous les symboles.
Le nombre de 0 et/ou de # dans le pattern détermine la taille des parties entière et décimale de la valeur numérique, sachant que 0 représentera un chiffre obligatoirement présent (et éventuellement remplacé par un zéro inutile) et # un chiffre optionnel (qui ignorera donc les zéros inutiles).
Par exemple, pour afficher un nombre réel avec 2 décimales, on utilisera le code suivant :
Code Java : | Sélectionner tout |
1 2 | DecimalFormat df = new DecimalFormat("0.00"); System.out.println(df.format(mon_nombre)); |
Vous trouverez dans le tableau suivant quelques exemples de pattern :
Format | 0 | 0,02 | 0,8 | 12,9 |
# | 0 | 0 | 1 | 13 |
### | 0 | 0 | 1 | 13 |
0 | 0 | 0 | 1 | 13 |
000 | 000 | 000 | 001 | 013 |
#.## | 0 | 0,02 | 0,8 | 12,9 |
0.## | 0 | 0,02 | 0,8 | 12,9 |
0.00 | 0,00 | 0,02 | 0,80 | 12,90 |
#.00 | ,00 | ,02 | ,80 | 12,90 |
#,##0.00 | 0,00 | 0,02 | 0,80 | 12,90 |
À noter que toutes les caractéristiques du pattern peuvent être modifiées par les méthodes de la classe DecimalFormat, et que la classe NumberFormat permet d'obtenir un certain nombre de formatages standard via des méthodes statiques.
Enfin, à partir de Java 5.0, il est possible d'utiliser une syntaxe proche du printf() du C via la classe java.util.Formatter. Dans la pratique on n'utilisera pas directement cette classe, mais des méthodes l'utilisant comme PrintStream.printf() ou String.format().
Cette syntaxe différencie les types entiers (short, int, long et BigInteger) des types réels (float, double et BigDecimal).
Les types entiers sont représentés par la syntaxe %d :
Code Java : | Sélectionner tout |
System.out.printf ("%d", 12); // Affiche 12
Syntaxe | Exemple | Description |
%d | "12" | Valeur entière. |
] | " 12" | Valeur entière sur 5 caractères minimum (complété par des espaces avant le nombre). |
%-5d | "12 " | Valeur entière sur 5 caractères minimum (complété par des espaces après le nombre). |
%05d | "00012" | Valeur entière sur 5 chiffres minimum, complétée par des zéros. |
Code Java : | Sélectionner tout |
System.out.printf ("%f", 1234.567); // Affiche 1234,567000
Quelques exemples de formatage pour la valeur 1234.567 :
Syntaxe | Exemple | Description |
%f | "1234,567000" | Valeur réelle avec 6 décimales par défaut.Valeur réelle avec 6 décimales par défaut. Valeur réelle avec 6 décimales par défaut. |
_ | "1234,567000" | Valeur réelle sur 5 caractères minimum (partie entière + décimale). |
%.0f | "1235" | Partie entière sans décimale. |
%.2f | "1234,57" | Valeur réelle avec 2 décimales. |
%2F | " 1234,57" | Valeur réelle sur 10 caractères minimum, avec 2 décimales |
%,.2f | "1 234,57" | Valeur réelle avec 2 décimales et séparateur de millier. |
La documentation de la classe java.util.Formatter contient toutes les informations détaillées sur la syntaxe à utiliser.
Note : Ces deux solutions (Formatter et DecimalFormat) utilisent les spécificités de la locale par défaut pour formater la chaîne de caractères (caractère de séparation des milliers, des décimales, etc.). Il est bien sûr possible de préciser une autre locale via les paramètres des méthodes ou du constructeur.
Conversion en base 2, 8, 16 : int toXXXString()
La classe Integer dispose de trois méthodes statiques permettant de convertir un entier décimal en une chaîne représentant son équivalent binaire, octal et hexadécimal.
Code java : | Sélectionner tout |
1 2 3 4 | int intBase10 = 192; String intBase2 = Integer.toBinaryString(intBase10); // "11000000" String intBase8 = Integer.toOctalString(intBase10); // "300" String intBase16 = Integer.toHexString(intBase10); // "c0" |
Afin d'obtenir la représentation dans la base de son choix d'un entier décimal, la classe Integer dispose des méthodes statiques toString().
Code java : | Sélectionner tout |
1 2 3 4 | int intBase10 = 19587; String intBase2 = Integer.toString(intBase10,2); // "100110010000011" String intBase5 = Integer.toString(intBase10,5); // "1111322" String intBase27 = Integer.toString(intBase10,27); // "qnc" |
Méthode parseXXX()
La conversion de chaînes de caractères en valeurs numériques est assurée par les différentes classes de gestion des types de base de Java : java.lang.Integer, java.lang.Double, java.lang.Float, java.lang.Long et java.lang.Byte. La chaîne de caractères ne doit contenir que le nombre à convertir : toute erreur génère l'exception java.lang.NumberFormatException.
Code Java : | Sélectionner tout |
1 2 3 4 | int i = Integer.parseInt(maString); long l = Long.parseLong(maString); byte b = Byte.parseByte(maString); // etc. |
Code Java : | Sélectionner tout |
Integer.parseInt(hexa, 16);
Méthode XXXXFormat.parse(pattern)
Une autre méthode, plus lourde, mais aussi plus flexible consiste à utiliser un Formatter pour parser la chaîne de caractères en nombre. Cette méthode vous permet de parser les nombres en tenant compte de l'internationalisation du séparateur décimal.
Code Java : | Sélectionner tout |
1 2 3 4 5 | NumberFormat monFormatteurDeNombre = NumberFormat.getInstance(); // par défaut localisation France sur mon ordinateur String maChaine = "1053,52"; double resultat = monFormatteurDeNombre.parse(maChaine).doubleValue(); // Le parse doit attraper l'exception ParseException |
Méthode parseInt()
La méthode statique parseInt() de la classe Integer permet de convertir une chaîne représentant un nombre entier en base quelconque en un entier décimal.
Code Java : | Sélectionner tout |
1 2 3 4 5 6 | parseInt("99", 8); // throws a NumberFormatException parseInt("Kona", 10); // throws a NumberFormatException parseInt("Kona", 27); //returns 411787 parseInt("-0", 10); //returns 0 parseInt("-FF", 16); //returns -255 parseInt("1100110", 2); //returns 102 |
Méthode decode()
La méthode decode() de la classe Integer permet de convertir en Integer une chaîne vérifiant la grammaire suivante :
- (-) DecimalNumeral
- (-) 0x HexDigits
- (-) 0X HexDigits
- (-) # HexDigits
- (-) 0 OctalDigits
En Java les types de base sont passés aux méthodes par valeur, ils ne peuvent pas être modifiés. Il va falloir utiliser une instance de classe « encapsulant » un entier pour effectuer la modification. Attention la classe fournie Integer ne permet pas la modification et est donc inutile dans ce cas.
Exemple :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class MonEntier { /** champ privé : */ private int value; /** mise à jour de la valeur */ public void setValue(int newValue) { value = newValue; } /** Accès à la valeur */ public int getValue() { return( value); } } |
Dans la méthode maMethode faire :
Code java : | Sélectionner tout |
1 2 3 | public void maMethode (MonEntier i) { i.setValue(maNouvelleValeur); } |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.