next up previous contents index
Next: Nombres aléatoires Up: No Title Previous: Caractères

Types flottants

         

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 dyadiques 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 tex2html_wrap_inline5384 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 (Cray étant une exception notable). Cette norme distingue deux niveaux de précision : simple (sur 4 octets) et double (sur 8 octets).

Prenons l'exemple des flottants en simple précision ; les 32 bits tex2html_wrap_inline5386 sont répartis en :

La valeur d'un flottant normalisé est tex2html_wrap_inline5394 , où

   figure1155
Figure: Flottants

Dans l'exposant, soustraire 127 permettrait de représenter le plus petit exposant, tex2html_wrap_inline5402 , par les bits 0000 0000 et le plus grand exposant, tex2html_wrap_inline5404 , par les bits 1111 1111 ; tex2html_wrap_inline5406 est par exemple représenté par 0111 1111. En fait, 0000 0000 et 1111 1111 ont des significations spéciales, pour représenter 0, tex2html_wrap_inline5408 , et NaN (c'est-à-dire Not a Number) ; les exposants extrêmes des flottants normalisés sont donc tex2html_wrap_inline5410 (par 0000 0001) et tex2html_wrap_inline5412 (par 1111 1110).

La valeur de la mantisse étant toujours tex2html_wrap_inline5414 , 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 tex2html_wrap_inline5416 (et non tex2html_wrap_inline5418 ). Il y aurait alors un << trou >> entre 0 et le plus petit nombre normalisé, qui a comme bits d'exposant 0000 0001 et les bits de mantisse nuls. Pour combler ce trou, on convient que si les 8 bits d'exposant sont nuls, la valeur est un flottant dénormalisé, de valeur tex2html_wrap_inline5420 .

 

Si les bits d'exposant valent 1, et les bits de mantisse valent 0, la valeur est tex2html_wrap_inline5422 , 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 , tex2html_wrap_inline5426 , ou tex2html_wrap_inline5428 .

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 tex2html_wrap_inline5434 converge !

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. Il y a en C plusieurs niveaux de précision, qui caractérisent différents types flottants : float (sur 4 octets), double (sur 8) et long double (sur 8 ou 16). Diverses constantes sont définies dans float.h :

Il y a des constantes analogues DBL_EPSILON, DBL_MIN et DBL_MAX pour le type double.

On ne testera jamais l'égalité de deux flottants avec == ou != ; il est préférable de tester un écart relatif :

  if (fabs(x-y) < epsilon * x) { ... }

Les valeurs de type double peuvent être notées avec un signe, un point décimal et un exposant optionnel. Pour le type float, la constante doit être terminée par f :

const double pi = 3.141592653;
const float avogadro = 6.02e23f;

Un nombre flottant peut être lu sur l'entrée standard avec la fonction scanf, et écrit sur la sortie standard avec printf ; en écriture, on utilise la conversion %f pour la notation flottante ou %e pour la notation scientifique ; la lecture d'un double utilise la conversion %lf:

   

  float x;
  double y;
  scanf("%f%lf", &x, &y);
  printf("%f\t%e%f\t%e", x, x, y, y);

La précision peut être indiquée entre le % et le caractère f ou e : %6.2f spécifie une impression sur au moins 6 caractères, dont 2 après le point décimal, le tout calé à droite.


next up previous contents index
Next: Nombres aléatoires Up: No Title Previous: Caractères

Rene Lalement
Mon Sep 30 18:22:54 MET 1996