Plus grave que le bug du Pentium !
Le bug du Pentium, une "simple" erreur de
calcul, a
fait
beaucoup de bruit au début de l'année 1994. Mais qui se souvient
que ses ancêtres (486, 386 et les autres) ont connus le même
type de problème ? Passons. Sous la pression des consommateurs, Intel
avait du se résoudre à retirer tous ses processeurs "
défectueux " du marché. Précisons que nous ne
parlons que de cette erreur - il en reste certainement d'autres...
Désormais,
Intel vous garantit que votre microprocesseur calcule juste. En êtes
vous si sûr ?
Pour ceux qui ont la chance d'être resté sous Windows
3.1,
lancez l'accessoire calculatrice. Faites 123,45 - 123,46. Vous trouvez
combien
? -0,01000000000001... J'en voie qui rigolent dans le fond : vous avez
fait
l'essai sous Windows 95 et vous trouvez le 0,01 attendu ? Ne rigolez
pas
: pour une erreur corrigée, vous avez combien de bugs supplémentaires
? En plus, j'aurais pu choisir un exemple qui aurait donné un bon
résultat avec Windows 3.1 et un faux chez vous... Zut, il s'agit
donc d'une erreur logicielle. On recommence.
Prenons maintenant le Basic (GW ou Quick) et effectuons
&laqno;1000,1111
- 0,1111». De tête, vous me dites 1000. Bien. Ce n'est pas si
évident pour votre PC. Quel que soit son microprocesseur (du 8086
au Pentium Pro), il vous répondra invariablement 999,9999968767.
Certes, l'erreur est infime, mais comme dit le proverbe &laqno;Les
petits
ruisseaux font les grandes rivières».
Tous les processeurs seraient ils donc vraiment bogués
jusqu'à
la moelle ?
Stop ! Ne criez pas à l'arnaque ! N'injuriez pas Intel
et
n'appelez
pas la police ! Votre Pentium n'est pas coupable. Enfin pas vraiment :
vous
obtiendriez des résultats plus ou moins faux avec presque n'importe
quel microprocesseur non Intel ! Explication...
Comme vous l'avez appris à l'école, les nombres se
divisent
en deux grandes familles : les entiers naturels et les réels décimaux.
Toute la différence est dans la virgule... Y'en a qui en ont, d'autres
pas. A la base, l'ordinateur ne connait que les 0 et les 1 : les bits.
De
là, il en déduit tous les entiers car en partant de zéro
et en ajoutant un, plus un, puis encore un (etc...) on peut obtenir
n'importe
quel nombre. Mais regardons ces bits d'un peu plus prêt.
Avec un bit on code deux valeurs (zéro ou un), avec deux
bits
quatre (2 x 2 : deux possibilités pour le premier, idem pour le second)
et avec trois bits huit (2 x 2 x 2). Chaque bit codera une puissance de
2, le premier noté 21 (= 2), le deuxième 22 (= 4), troisième
23 (= 8) et ainsi de suite 16, 32, 64 et 128. On appelle un ensemble de
8 bits un octet. Un octet permet de coder 256 valeurs, soit 28 (exemple
1). On peut ensuite assembler les octets entre eux pour obtenir des
nombres
de plus en plus grands. Seule limite : la capacité mémoire
de votre ordinateur.
Malheureusement, les entiers ne sont pas suffisants pour
décrire
le monde qui nous entoure. Les mathématiciens grecs l'ont compris
les premiers : les nombres à virgules, les réels, sont indispensables.
Avec l'ordinateur, c'est là que commencent les problèmes...
Si avec les entiers on peut connaître tous les nombres compris dans
un intervalle, les réels sont eux indénombrables. C'est à
dire que même en se fixant des limites, un minimum et un maximum,
le nombres de valeurs dans cet ensemble est illimité. Dans ce contexte,
l'ordinateur est obligé de rapprocher une valeur donnée de
la valeur connue la plus proche. D'où des erreurs de calculs.
Ainsi, on le voit (exemple 2), il est impossible de
coder 0,6
sur 8 bits
! Cet exemple de codage très simplifié n'est que rarement
utilisé dans la pratique. En effet, il existe une multitude de façons
de stocker les nombres et avec lesquelles 0,6 serait possible. Mais le
problème
n'aurait été que repoussé à une autre échelle.
Une erreur ? C'est la faute à l'ordinateur !*
Première expérience : prenez une calculatrice. Calculez
la racine de 2, puis la racine de cette racine, répétez l'opération
vingt fois. Puis faites le contraire : appuyez la puissance de deux,
vingt
fois de suite. Au mieux vous obtiendrez 2,00000000157 au pire 1, jamais
le 2 prévu. La précision dépend du nombre de bit utilisés
pour coder les réels. Plus le nombre de bits est important, plus
la précision sera bonne. Mais en poursuivant les calculs, on arrivera
toujours à une erreur.
Deuxième expérience :
Voici les deux calculs que nous allons effectuer.
u=( ( y+ x ) - x ) / y v= ( y + ( x - x ) ) / y
avec x = 1 et y = 10-40
Même un enfant de 12 ans, après application des lois de
l'associativité et de la commutativité, nous dirait que le
résultat est identique et vaut 1. Pour un ordinateur pas très
doué, après approximation, y sera vu comme trop
petit
devant 1 et vaudra zéro, on aura donc comme résultat :
u= 0 / y = 0 v = y / y = 1
Vous voyez le résultat déjà avec des exemples simples.
Alors imaginez ce qui doit se passer dans l'ordinateur de votre banque
après
des millions d'opérations chaque seconde !
Quelques principes permettent de minimiser les erreurs :
augmenter le
nombre de bits significatifs (on arrive à 19 chiffres significatifs
en codant sur 10 octets, soit 80 bits), faire très attention sur
les calculs mettant en regard deux nombres présentant une très
grande différence, simplifier au maximum les calculs avant de les
effectuer, etc. Mais dans bien des cas, les erreurs existeront toujours
!
Alors un conseil : ne faites pas trop confiance à la
machine.
Sylvain Cadet
*et pour une fois c'est vrai !
exemple 1 :
on code l'entier 221 en binaire :
1 1 0 1 1 1 0 1
valeur de chaque bit :
128 64 32 16 8 4 2 1
128 +64 +0 +16 +8 +4 +0 +1 font bien 221
exemple 2 :
on code le réel 0,6 en binaire. Avec les nombres à
virgule
c'est pareil que précédemment, sauf qu'on prend les puissances
inverses de 2. C'est à dire qu'on divise le bit par 2, 4, 8, etc.
1 0 0 1 1 0 0 1
valeur de chaque bit
0,5 0,25 0,125 0,0625 0,03125 0,015625 0,0078125
0,00390625
1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256
0,5 +0 +0 +0,0625 +0,03125 +0 +0 +0,00390625
soit 0,59765625 au mieux.

|