Nombres "flottants"

images/whitebelt.png

Il est possible de noter des valeurs littérales pour des nombres décimaux.

jshell> 19.99
$1 ==> 19.99

jshell> 3E-18  // notation scientifique: ici puissance négative donc un nombre très petit
$2 ==> 3.0E-18

jshell> 3D    // ce n'est pas un entier
$3 ==> 3.0

jshell> .3
$4 ==> 0.3

C’est le standard américain qui s’impose ici: le séparateur décimal est un point pas une virgule.

[Note]

Cette utilisation du point s’impose au programmeur. On pourrait penser qu’il serait dommage qu’elle s’impose à un utilisateur lors d’une saisie de valeur!

Soyez rassuré il est possible d’assurer des interactions selon les conventions de la langue et du pays : ce sera le rôle d’un code particulier java.text.DecimalFormat

Opérations

Les opérations sur ces nombres se notent comme pour les nombres entiers:

jshell> 19.99 + 39.99  // addition
$1 ==> 59.980000000000004

jshell> 19.99 - 39.99 // soustraction
$2 ==> -20.000000000000004

jshell> 19.99 * 2D   // multiplication
$3 ==> 39.98

jshell> 100D/3D      // division
$4 ==> 33.333333333333336

jshell> 19.99 % 10.1 // modulo
$5 ==> 9.889999999999999

Ici aussi on peut être surpris des résultats … mais tout s’explique: on manipule des valeurs associées à des représentations internes d’un coprocesseur arithmétique. Voir: wikipedia: virgule flottante. Ces nombres sont appelés "nombres flottants". Ici c’est un type java appelé double (d’où la notation avec un "D" en fin de littéral) et codé sur 64 bits.

Encore une fois il s’agit d’une représentation de bas niveau mais portable entre architectures différentes (représentation proche de la norme IEEE 754 mentionnée dans l’article).

On obtient donc des calculs rapides mais "bruts" et il faudra en adapter les résultats. Les pratiques diffèrent selon que l’on fait des calculs financiers ou des calculs scientifiques.

Limites

images/orangebelt.png

On ne peut, bien entendu, représenter tous les nombres décimaux possibles sur un processeur arithmétique. On a seulement accès à certaines valeurs et on dispose aussi de quelques valeurs remarquables:

jshell> 127.33/0D
$6 ==> Infinity

jshell> -127.33/0D
$7 ==> -Infinity

jshell> 127.33/-0D // notez le zéro négatif!
$8 ==> -Infinity

jshell> (127.33/-0D) + 3D
$9 ==> -Infinity

jshell> (127.33/-0D) * (127.33/0D)
$10 ==> -Infinity

jshell> (127.33/-0D) / (127.33/-0D) // NaN -> Not A Number
$11 ==> NaN

Si vous voulez approfondir vos connaissances théoriques sur les nombres flottants: wikipedia: la norme IEEE 754 (voir également la version en Anglais de l’article).

En conclusion: les manipulations de nombres flottants offrent un service rapide et intéressant mais il faut en connaître les limitations. Nous verrons ultérieurement comment opérer des calculs avec des contrôles de précision avec un type java.math.BigDecimal (Cela vous permettra, par exemple, de calculer la valeur en Euros de 166 milliards de Yens avec un taux de conversion comprenant 6 chiffres après la virgule et un résultat ne comportant que deux chiffres après la virgule).

--exercices-- : expérimentez! Avec Jshell en mode ligne à ligne manipulez des valeurs flottantes et exécutez des opérations et des combinaisons d’opérations de plus en plus complexes.