Scalaires
Faisons un rappel succinct du calcul scalaire dans les programmes.
En dehors de toutes les représentations symboliques des scalaires,
via les types simples, il y a deux grandes catégories d'objets
scalaires dans les programmes: les entiers en virgule fixe, les
réels en virgule flottante.
Les entiers
Le calcul entier est relativement simple. Les nombres sont en fait
calculés dans une arithmétique modulo N = 2n où n est le
nombre de bits des mots machines.
n | N | | Exemple |
16 | 65 536 | = 6 × 104 | Macintosh SE/30 |
32 | 4 294 967 296 | = 4 × 109 | Pentium |
64 | 18 446 744 073 709 551 616 | = 2 × 1019 | Alpha |
|
Figure i.1 : Bornes supérieures des nombres entiers
Ainsi, les processeurs de 1992 peuvent avoir une arithmétique
précise sur quelques milliards de milliards, 100 fois plus rapide
qu'une machine 16 bits! Il faut toutefois faire attention à la
multiplication ou pire à la division qui a tendance sur les machines
RISC (Reduced Instruction Set Computers) à prendre beaucoup
plus de temps qu'une simple addition, typiquement 10 fois plus
sur le processeur R3000 de Mips. Cette précision peut être
particulièrement utile dans les calculs pour accéder aux fichiers.
En effet, on a des disques de plus de 4 Giga Octets actuellement, et
l'arithmétique 32 bits est insuffisante pour adresser leurs contenus.
Il faut pouvoir tout de même désigner des nombres négatifs. La
notation couramment utilisée est celle du complément à 2. En notation
binaire, le bit le plus significatif est le bit de signe. Au lieu de
parler de l'arithmétique entre 0 et 2n - 1, les nombres sont pris
entre -2n-1 et 2n-1 - 1. Soit, pour n=16, sur l'intervalle
[-32768, 32767]. En Java, Integer.MAX\_VALUE
=
2n-1 - 1 est le plus grand entier positif et
Integer.MIN\_VALUE
= - 2n-1 le plus petit
entier négatif. En Caml, max\_int
= 2n-2 - 1 et
min\_int
= -2n-2.
Une opération entre 2 nombres peut créer un débordement,
c'est-à-dire atteindre les bornes de l'intervalle. Mais elle respecte
les règles de l'arithmétique modulo N. Selon le langage de
programmation et son implémentation sur une machine donnée, ce
débordement est testé ou non. Ni Java, ni Caml ne font ces tests.
Les nombres flottants
La notation flottante sert à représenter les nombres réels pour
permettre d'obtenir des valeurs impossibles à obtenir en notation
fixe. Un nombre flottant a une partie significative, la
mantisse, et une partie exposant. Un nombre flottant tient
souvent sur le même nombre de bits n qu'un nombre entier. En
flottant, on décompose n = s + p + q en trois champs pour le signe,
la mantisse et l'exposant, qui sont donnés par la machine. Ainsi
tout nombre réel écrit ``signe decimal
e
exposant'' en Java ou Caml, vaut
Les nombres flottants sont une approximation des nombres
réels, car leur partie significative f ne tient que sur un nombre
p de bits fini. Par exemple, p = 23 en simple précision. Le
nombre de bits pour l'exposant e est q = 8 en simple précision,
ce qui fait que le nombre de bits total, avec le bit de signe, est
bien 32.
Pour rendre portables des programmes utilisant les nombres flottants,
une norme IEEE 754 (the Institute of Electrical and Electronics
Engineers) a été définie. Non seulement elle décrit les bornes
des nombres flottants, mais elle donne une convention pour
représenter des valeurs spéciales: ± ¥, NaN (Not A
Number) qui permettent de donner des valeurs à des divisions par
zéro, ou à des racines carrées de nombres négatifs par exemple.
Les valeurs spéciales permettent d'écrire des programmes de calcul
de racines de fonctions éventuellement discontinues.
La norme IEEE est la suivante
|
Exposant | Mantisse | Valeur |
|
e = emin - 1 | | f = 0 | | ± 0 |
e = emin - 1 | | f ¹ 0 | | 0,f × 2emin |
emin £ e £ emax | | | | 1,f × 2e |
e = emax + 1 | | f = 0 | | ± ¥ |
e = emax + 1 | | f ¹ 0 | | NaN |
|
| |
Figure i.2 : Valeurs spéciales pour les flottants IEEE
et les formats en bits simple et double précision sont
|
Paramètre | Simple | Double |
|
p | | 23 | | 52 |
q | | 8 | | 11 |
emax | | +127 | | +1023 |
emin | | -126 | | -1022 |
Taille totale du mot | | 32 | | 64 |
|
| |
Figure i.3 : Formats des flottants IEEE
On en déduit donc que la valeur absolue de tout nombre flottant x
vérifie en simple précision
10-45 » 2-150 £ |x| < 2128 » 3
× 1038
et en double précision
2 × 10-324 » 2-1075 £ |x| < 21024
» 10308
Par ailleurs, la précision d'un nombre flottant est
2-23 » 10-7 en simple précision et 2-52 » 2
× 10-16 en double précision. On perd donc 2 à 4 chiffres
de précision par
rapport aux opérations entières. Il faut comprendre aussi que les
nombres flottants sont alignés avant toute addition ou soustraction,
ce qui entraîne des pertes de précision. Par exemple, l'addition d'un
très petit nombre à un grand nombre va laisser ce dernier inchangé.
Il y a alors dépassement de capacité vers le bas (underflow). Un
bon exercice est de montrer que la série harmonique converge en
informatique flottante, ou que l'addition flottante n'est pas
associative! Il y a aussi des débordements de capacité vers le haut
(overflows). Ces derniers sont en général plus souvent
testés que les dépassements vers le bas.
Enfin, pour être complet, la représentation machine des nombres
flottants est légèrement différente en IEEE. En effet, on s'arrange
pour que le nombre 0 puisse être représenté par le mot machine dont
tous les bits sont 0, et on additionne la partie exposant du mot
machine flottant de emin - 1, c'est-à-dire de 127 en simple
précision, ou de 1023 en double précision.