Représentation des nombres dans un ordinateur Représentation des entiers naturels en base p Soit b un entier naturel 2 appelée la base. Alors tout entier naturel n > 0 s'écrit de façon unique sous la forme n = d 0 + d 1 b + d 2 b 2 + + d m b m avec d i 0, b 1, d m 0. m étant un entier positif caractérisé par b m n < b m + 1 Cette écriture s'appelle la décomposition de l'entier n en base b. On écrit simplement, le chiffre des unités d 0 étant à droite. Preuve n = d m d m 1... d 0 Pour l'existence, on procède par récurrence sur n. Initialisation : c'est vrai pour n = 1 : prendre m = 0, d 0 = 1 < b. hérédité : supposons la propriété vraie pour tous les entiers qui sont n 1 et prouvons là alors pour l entier n. La division euclidienne de n par b s'écrit n = ab + d 0 avec 0 d 0 < b. On applique l hypothèse de récurrence à l entier a : il existe un entier m 0 tel que, a = d 1 + d 2 b + d 3 b 2 + + d m b m 1 d'où, n = (d 1 + d 2 b + d 3 b 2 + + d m b m 1 ) b + d 0 = d 0 + d 1 b + d 2 b 2 + + d m b m Pour l'unicité, on procède aussi par récurrence. Supposons qu'on ait deux écritures pour l'entier n : n = d 0 + d 1 b + d 2 b 2 + + d m b m = d' 0 + d' 1 b + d' 2 b 2 + + d' q b q Vu l'écriture, d 0 = d' 0 est forcément le reste dans la division euclidienne de n par b. On a l'unicité du quotient dans cette division. D'où, a = d 1 + d 2 b + d 3 b 2 + + d m b m 1 = d' 1 + d' 2 b + d' 3 b 2 + + d' q b q 1 Par unicité de l'écriture de a, on a m = q et d 1 = d' 1,..., d m = d' m. Reste à voir l'affirmation sur m : La suite (b m ) m 0 est strictement croissante, donc tend vers + et il existe un unique entier m tel que b m n < b m + 1 (m est le plus grand entier k tel que b k n). On a b m n car d m 1. D'autre part, n (b 1)(1 + b + b 2 + + b m ) = b m + 1 1 < b m + 1 Remarque La preuve est constructive : en faisant des divisions euclidiennes par b de façon répétée, on trouve successivement d 0, d 1,..., d m. On s'arrête quand on trouve un quotient nul. Avec cette méthode, on trouve les chiffres en partant du chiffre des unités d 0. On peut aussi d'abord trouver l'entier m, l'entier d m (immédiat en base 2) puis retrancher d m b m et recommencer. Conversion entre bases 1) Ecriture de 178 en base 2 : 178 = 2 89 + 0, 89 = 2 44 + 1, 44 = 2 22 + 0, 22 = 2 11 + 0, 11 = 2 5 + 1, 5 = 2 2 + 1, 2 = 2 1 + 0, 1 = 0 2 + 1 On s'arrête quand on obtient un quotient nul. Le premier bit est celui des unités placé à droite. 178 = 10110010 = 1 2 7 + 1 2 5 + 1 2 4 + 1 2 1 - page 1 -
2) Ecrire 178 en base 3. 3) Donner l'écriture décimale de l'entier qui s'écrit 3600154 en base 7. Donner l'écriture décimale de l'entier (11010001011) 2 Cas particuliers Vu les processus électroniques en jeu dans un microprocesseur, on s'intéresse particulièrement aux cas b = 2 et b = 16. b = 2 on parle d'écriture binaire de l'entier n n = d 0 + 2d 1 + 2 2 d 2 + + d m 2 m, d i {0,1} Une unité élémentaire d'information prenant les valeurs 0 ou 1 est appelé bit. Les chiffres d i sont donc les bits de la décomposition binaire de n. Le terme vient de BInary digit (Shannon 1938). Le bit d m (le plus à gauche dans l'écriture n = d m d m 1... d 0 ) est appelé bit de poids fort. Le bit d 0 (le plus à droite dans l'écriture n = d m d m 1... d 0, c.a.d le chiffre des unités) est appelé bit de poids faible. b = 16 Dans ce cas, on parle d'écriture hexadécimale de n. On a d i 0,15. Pour éviter toute ambiguïté dans l'écriture d m d m 1... d 0, on remplace les chiffres hexadécimaux 10,11,12,13,14,15 par les lettres A, B, C, D, E et F. Ainsi, le nombre (3A) 16 désigne le nombre décimal 3 16 + 10 = 58. Quel est l'écriture hexadécimale de 178? Lien entre écriture binaire et hexadécimale 4 chiffres binaires donne un chiffre hexadécimal. Si dans l'écriture binaire d'un entier, on regroupe les bits par paquets de 4, chaque regroupement correspond à un chiffre hexadécimal, ce qui donne l'écriture hexadécimale de l'entier. Preuve n = ε i 2 i i 0 = (ε 4k + 2ε 4k + 1 + 4ε 4k + 2 + 8ε 4k + 3 ) 2 4k = d k 16 k k 0 k 0 avec d k = ε 4k + 2ε 4k + 1 + 4ε 4k + 2 + 8ε 4k + 3 0,15 qui est un chiffre hexadécimal. On obtient bien l'écriture hexadécimale en regroupant les bits de l'écriture binaire par blocs de 4 bits. Par exemple, un registre 32 bits s'écrira avec 8 chiffres hexadécimaux au lieu de 32 bits, ce qui est plus facile à lire! Définition Un octet est un nombre binaire à au plus 8 chiffres. C'est aussi un nombre hexadécimal à deux chiffres. Un octet est donc compris entre 0 et 11111111 (255 en décimal, FF en hexadécimal). Exercice : donner l'écriture hexadécimale du nombre binaire 1110010100001110. La capacité mémoire se mesure en ko (kilo-octets) ou ses multiples : Mo(mégaoctet), Go (gigaoctet), To (téraoctet), Un codage sur n bits permet plus généralement de représenter les entiers entre 0 et 2 n 1. Le nombre binaire 11... 1 (n bits égaux à 1) code l'entier 2 n 1. Un entier k codé sur n bits est dans l'intervalle 2 n 1, 2 n 1 ssi le bit de poids fort est égal à 1. - page 2 -
Addition en binaire Elle se fait comme en base 10 : on fait l'addition des bits de même poids avec retenue éventuelle, selon la règle, + 0 1 0 0 1 1 1 0 Par exemple, l'addition des nombres décimaux 105 et 92, se fait en binaire retenues 1 1 1 105 1 1 0 1 0 0 1 92 1 0 1 1 1 0 0 197 1 1 0 0 0 1 0 1 Multiplication ou division entière par une puissance de 2 Multiplier un nombre binaire par 2 k, c'est décaler l'écriture binaire de k positions vers la gauche. Le quotient dans la division d'un nombre binaire n par 2 k (division entière par 2 k ), s'obtient en décalant d'écriture binaire de k positions vers la droite, les k premiers bits (qui donnent le reste) étant perdus. Les microprocesseurs sont munis d'opérateurs de décalage vers la droite ou vers la gauche. Dans un ordinateur, faire une multiplication ou une division entière par une puissance de 2 se fait donc très facilement et en temps constant. Codage des entiers négatifs La première méthode consiste à réserver l'un des bits de l'écriture binaire pour spécifier le signe. Cela pose le problème de la somme de deux entiers signés. De plus, 0 possède deux écritures différenciées par la valeur du bit de signe. En revanche, calculer un opposé est facile et l'ensemble des nombres représentables est symétrique : sur n bits, on code tous les entiers de l'intervalle (2 n 1 1), 2 n 1 1. L'autre solution est la méthode du complément à 2 : On désire coder les entiers entre 2 n 1 et 2 n 1 1. Le codage se fait sur n bits, le bit de poids fort indiquant le signe : 1 pour un entier négatif, 0 pour un entier positif. Les entiers positifs entre 0 et 2 n 1 1 se codent de façon traditionnelle et ont donc un bit de poids fort nul. L'entier négatif k, est codé par l'entier positif 2 n k, ce qui revient à travailler modulo 2 n. Pour k 1, 2 n 1, 2 n k 2 n 1, 2 n 1. Un entier négatif se code donc bien par un nombre binaire à n chiffres avec un bit de poids fort égal à 1. L'entier 2 n 1 se code par 100... 0 et 1 se code par 111... 1. Propriété (méthode pratique) Soit un entier k 1, 2 n 1. On considère son écriture binaire sur n bits. On inverse tous les bits (complément à 2), c.a.d qu'on remplace 0 par 1 et 1 par 0, et enfin on ajoute1. On obtient ainsi l'écriture binaire de k. Preuve Notons k' l'entier obtenu en inversant tous les bits de l'écriture de k. On a k + k' = (11... 1) 2 = 2 n 1 donc k' + 1 = 2 n k qui est par définition l'entier qui code k. Avantages de la méthode du complément à 2 - page 3 -
L'addition se fait très simplement : étant donné deux entiers entre 2 n 1 et 2 n 1 1, les additionner revient à additionner leurs représentations binaires puisque les nombres sont définis modulo 2 n, le signe du résultat se lisant sur le bit de poids fort. Unicité du codage d'un entier donné. Inconvénients La taille maximale est fixée d'où des problèmes de débordement (overflow), l'addition de deux entiers positifs pouvant donner un entier négatif! Il faut donc bien contrôler la taille des entiers qu'on manipule. Crash d Ariane 5 lors de son premier vol à cause d'un dépassement de capacité dans le système informatique du guidage inertiel : l'accélération horizontale était codée sur 16 bits comme entier signé, donc comme entier entre 32767 et 32767 ce qui s'est avéré insuffisant et a généré des valeurs aberrantes qui ont déclenché l'autodestruction de la fusée.. - page 4 -
Nombres flottants L'analyse mathématique et sa branche numérique nécessitent l'emploi des nombres réels. Ces derniers possèdent en général un développement décimal illimité qui n'est pas représentable tel quel dans l'ordinateur. Le principe c'est que l'ordinateur fait des calculs approchés et qu'il faut s'assurer que les approximations qui sont faites tout du long des calculs, n'altèrent pas la fiabilité des résultats. Ce doit être un souci constant quand on fait de l'analyse numérique. L'échelle des nombres utilisés va des nombres très proches de 0 (concentrations en chimie par exemple) à des valeurs extrêmement grandes (données astronomiques par exemple). On doit pouvoir représenter toute cette gamme de valeurs. Notation scientifique Tout réel x non nul peut s'écrire sous la forme x = ε m 10 e avec ε = ± 1, m [1, 10[ (ou [1, b[ si on travaille en base b) et e. m s'appelle la mantisse et e s'appelle l'exposant. Le codage (ε, e, m) définit un nombre en virgule flottante ou nombre flottant. Il y a plusieurs façons de coder le triplet (ε, e, m) qui reposent sur la norme IEEE 754 : le recours à une norme est nécessaire pour qu'un même programme soit compatible sur des machines différentes. Ce ne serait pas le cas si ces machines avaient chacune un codage des réels différent. La norme fixe le format des nombres, les valeurs spéciales, les modes d arrondi, la précision des opérations de base, les règles de conversion. On écrit, p m = 1 + k = 1 m k 2 k, m k {0,1} ; m [1, 2 (1/2) p ] et m se code comme le nombre binaire à p chiffres p ( m k 2 k ) 2 p k = 1 p = m k 2 p k k = 1 Si on veut que e (2 q 1 1), 2 q 1, alors on code e par l'entier e + 2 q 1 1 qui est un entier dans 0, 2 q 1 et est q de la forme e k 2 k, e k {0,1}. L'exposant est donc codé comme nombre binaire à q bits. k = 0 Comme le signe se code sur un seul bit, en tout, il faut 1 + p + q bits pour coder un flottant. codage simple précision sur 32 bits (4 octets) p = 23, q = 8. L'exposant est donc dans 126, 127 et la mantisse de la forme 1,m 1 m 2... m 23. 2 23 = 8388608 (mantisse sur 7 chiffres décimaux), 2 127 1.7 10 38. codage double précision sur 64 bits (8 octets) p = 52, q = 11. L'exposant est donc dans (2 10 2), 2 10 1 = 1022, 1023 et la mantisse de la forme 1,m 1 m 2... m 52. 2 1023 9 10 307 Une fois p et q choisis, le nombre de réels qu'on peut représenter sous forme d'un flottant (ε, m, e) est fini. On note x min et x max les valeurs extrêmes représentables. Pour tout réel x compris entre x min et x max, on note x (resp. x + ) le plus grand réel représentable x (resp. le plus petit réel représentable x). On a donc x x x + et aucun réel n'est représentable dans l'intervalle ouvert ] x, x + [. - page 5 -
Il y 4 façons d'arrondir dans la norme IEEE 754, c'est à dire de choisir entre x et x + : arrondi vers 0 : on choisit entre x et x +, celui qui est le plus proche de 0, c.a.d celui dont la valeur absolue est la plus petite. Cela revient à tronquer le développement binaire de x à p décimales. arrondi au plus proche : on choisit entre x et x +, celui qui est le plus proche de x. par exemple en simple précision, si la 24-ième décimale est 0, alors l arrondi consiste à tronquer le développement décimal de x à la 23-ième décimale ; si la 24-ième décimale est 1, alors l arrondi consiste à tronquer x à la 23-ième décimale et rajouter une unité à cette 23-ième décimale (on ajoute 2 23 ) (ce qui peut provoquer une retenue dans l addition). arrondi par x + (arrondi vers + ) arrondi par x (arrondi vers ) Soit x l arrondi d un réel x. L erreur absolue est = x x qui a même unité que x. et l erreur relative est λ = x x qui s exprime en pourcentage. x La norme IEEE754 spécifie aussi comment arrondir le résultat d une des 4 opérations de base ainsi que le résultat d une racine carrée. Ainsi, sur deux machines distinctes respectant la norme, les calculs donneront les mêmes résultats. Dans une addition, les erreurs absolues s additionnent. Dans une multiplication, les erreurs relatives s additionnent en première approximation. Les erreurs dues aux approximations Le problème vient des arrondis. L ensemble des nombres représentables en machine n est pas stable par les opérations. Le résultat d une opération est le flottant donné par la règle d arrondi en vigueur. La comparaison entre deux entiers est exacte (modulo la taille maximale admise pour les entiers). Pas contre, la comparaison entre deux flottants n est pas exacte à cause des problèmes d arrondi. exemple en Python : >>> 10*0.1 = = 1 True >>> 3*0.1 = = 0.3 False Cela s explique : en binaire, 0.1 s écrit 0,0001100110011001100110011001100110011001100110011001100110011... Le codage en double précision se fait avec une mantisse de 52 chiffres arrondie au plus proche, c.a.d 1.1001100110011001100110011001100110011001100110011010 2 4 ce qui donne en décimal 0.1000000000000000055511151231257827021181583404541015625 0.3 s'écrit en binaire 0.010011001100110011001100110011001100110011001100110011001... codé en double précision par 1,0011001100110011001100110011001100110011001100110011 2 2 ce qui donne en décimal 0.299999999999999988897769753748434595763683319091796875 Python retourne 3*0.1 = 0.30000000000000004. Cela s'explique aussi : 3 s'écrit en binaire 11 et on a vu que 0.1 est codé par 1.1001100110011001100110011001100110011001100110011010 2 4. - page 6 -
La multiplication 3*0.1 en binaire donne (avec la règle de l'arrondi au plus proche) : 0.010011001100110011001100110011001100110011001100110100 dont le développement décimal est 0.300000000000000044408920985006261616945266723632812500 Il n'y a pas d associativité pour l addition et la multiplication : (0.1 + 0.1 + 0.1) 0.3 = 5.551115123125783e-17 tandis que (0.1 + 0.1) + (0.1 0.3) = 2.7755575615628914e-17 (0.1 * 3) * 10 = 3.0000000000000004 tandis que 0.1*(3*10) = 3.0 Phénomène d'absorption Cela se produit quand on additionne deux nombres de tailles différentes. On peut perdre des chiffres significatifs du nombre le plus petit. 1235487 + 0.0000000004578 donne 1235487.0000000005 au lieu de 1235487.00000000045780 Phénomène d'élimination Cela se produit lors de la soustraction de deux nombres très proches. Il y a une diminution du nombre de chiffres significatifs. Si en plus, les deux nombres en question sont eux-mêmes entachés d'erreur (résultats de mesure par exemple), alors on peut obtenir un résultat sans aucun chiffre fiable. 0.000000458(244) 0.000000457(8945) donne 3.495000000000125e-10. Les chiffres entre parenthèses sont supposés être non fiables. Le résultat ne porte que sur ces chiffres non fiables et on a aucun chiffre significatif fiable dans le résultat. Quand on combine les deux phénomènes, on peut obtenir des résultats complètement aberrants. S'il s'agit de calculs intermédiaires, il peut-être difficile d'identifier la source des erreurs. En plus, l'apparition de ces phénomènes peut dépendre de la façon dont est organisé le calcul et des éventuelles transformations ou simplifications mathématiques que le concepteur du calcul aura mis en oeuvre. D'une façon générale, on doit se méfier des calculs produisant des résultats proches de 0. Considérons par exemple On obtient le tableau suivant : u n = (1 + 10 n ) 1 10 n n 0 1.0 2 1.0 4 1.0 5 1.00000000001 8 0.999999993923 9 1.00000008274 10 1.00000008274 11 1.00000008274 12 1.00008890058 13 0.999200722163 14 0.999200722163 15 1.11022302463 16 0.0 17 0.0 u n - page 7 -
Commenter les résultats. Un traitement mathématique préalable peut parfois suffire à éviter les quantités proches de 0. 1 + x 1 Par exemple, plutôt que de calculer qui va générer des quantités proches de 0 lorsque x est lui même proche x 1 de 0, on aura intérêt à calculer 1 + x + 1. Accumulation erreurs Selon le mode d'arrondi choisi, les erreurs peuvent se cumuler ou se compenser en moyenne (si elles ont un caractère aléatoire). Exemple : bourse de Vancouver - page 8 -