Les flottants sont des représentations en mémoire d'une partie des
nombres rationnels ; il est évidemment impossible de représenter des
nombres réels quelconques, pour des raisons de cardinalité. Seuls les
rationnels dont la forme irréductible est n/2q, peuvent avoir une
représentation exacte ; les autres ont nécessairement une représentation
approchée (par exemple, le nombre décimal 1/10 a
comme représentation en base 2, la
partie soulignée étant répétée indéfiniment). Cette représentation fait
l'objet de la norme IEEE 754, proposée par William Kahan (Turing
Award 1989), publiée en 1985 et adoptée par la plupart des fabricants
d'ordinateurs. Cette norme distingue deux niveaux de précision : simple
(sur 4 octets) et double (sur 8 octets), qui sont
implémentés en Java par les types primitifs float et
double. Il est souhaitable que le numéricien programmeur ait
une idée de l'implémentation des flottants, sans qu'il doive
nécessairement en connaître tous les détails.
Un nombre flottant est caractérisé par trois blocs de bits, qui déterminent respectivement son signe, son exposant et sa mantisse. Chacun de ses blocs est de taille fixe :
simple précision | double précision | |
taille | 32 bits | 64 bits |
signe | 1 bit, b31 | 1 bit, b63 |
exposant | 8 bits,
![]() |
11 bits,
![]() |
mantisse | 23 bits,
![]() |
52 bits,
![]() |
La valeur d'un flottant (s,e,m) est
,
où, dans le cas de la simple précision :
Dans l'exposant, soustraire 127 permettrait de représenter le plus petit
exposant, -127, par les bits 0000 0000 et le plus grand
exposant, 128, par les bits 1111 1111 ; 20 est par exemple
représenté par 0111 1111. En fait, 0000 0000 et
1111 1111 ont des significations spéciales, pour représenter 0,
,
et NaN (c'est-à-dire Not a Number) ; les
exposants extrêmes des flottants normalisés sont donc -126 (environ
10-38, par 0000 0001) et 127 (environ 1038, par
1111 1110).
La valeur de la mantisse étant toujours
,
zéro n'est pas
représentable dans ce schéma ; par convention, le bit de signe suivi de
31 bits nuls représentent la valeur
(et non
)4.1.
Si les bits d'exposant valent 1, et les bits de mantisse valent
0, la valeur est
,
qui est obtenue dans le cas
d'une division par 0. Enfin, si les bits d'exposant valent 1,
et les bits de mantisse ne sont pas tous nuls, la valeur est NaN,
qui peut être obtenue comme le résultat d'opérations illicites, comme
0/0 ,
,
ou
.
Bien que portant les mêmes noms (addition, multiplication), les
opérations flottantes ne sont pas ces opérations mathématiques, et n'ont
pas les mêmes propriétés. Par exemple, l'addition n'est pas associative
: on peut vérifier que
(10000003.0 -10000000.0)+7.501 = 10.501, tandis
que
10000003.0 + (-10000000.0 +7.501) = 11.0. Autre exemple : la série
converge !
Aux types primtifs float et double sont associées les classes enveloppantes Float et Double , qui définissent diverses constantes du type primitif correspondant :
MIN_VALUE
, la plus petite valeur >0 ;
MAX_VALUE
, la plus grande valeur >0 ;
POSITIVE_INFINITY
, NEGATIVE_INFINITY
et NaN
.
Les valeurs de type double peuvent être notées avec un signe, un point décimal et un exposant optionnel, par exemple -2.3e+4. Pour le type float, la constante doit être terminée par F (ou f) : 3.141592653 est un double, 6.02e23F est un float. D'autre part, une chaîne de caractères (provenant par exemple d'une lecture sur l'entrée standard) peut être convertie en flottant de la façon suivante :
String s = "12.3"; double x = Double.parseDouble(s); // x = 12.3