TP 4 : Écriture des nombres et mémoire
Transcription
TP 4 : Écriture des nombres et mémoire
TP 4 : Écriture des nombres et mémoire Combien vaut un kilooctet ? • Historiquement, un kilooctet était égal à 210 = 1024 octets (car le système binaire fait jouer un rôle particulier aux puissances de 2 et les quantités de mémoire des ordinateurs étaient des multiples de 2). • Cependant, ce choix n’était pas conforme à l’usage du préfixe « kilo » pour les autres unités. Une nouvelle norme a donc été crée : on a défini le kibioctet qui vaut 1024 octets (le préfixe « kibi » signifiant 1024) ce qui permet de revenir à l’usage habituel pour kilooctet, qui est donc égal à 1000 octets. • Cependant, ces dénominations sont peu utilisées en pratique et il règne donc une certaine confusion. Dans ce TP, les quantités de mémoire seront données en octets puis converties lorsque c’est pertinent en kibioctets (1024 octets, symbole kio) ou mébioctets (1024 kibioctets, symbole Mio). En effet, bien qu’elles soient peu connues, il n’y a aucune ambiguité lorsque l’on utilise ces unités. Remarque. Pour les trois premiers exercices, il n’y a pas de programme à écrire mais on pourra au besoin utiliser P YTHON comme une calculatrice pour effectuer les calculs demandés. Exercice 1. Estimer la capacité mémoire nécessaire pour stocker un livre de 200 pages (on considère que chaque caractère occupe 1 octet) ? Exercice 2. On considère un signal sonore échantillonné à la fréquence f = 44.1 kHz. Les échantillons sont enregistrés sur 16 bits et l’enregistrement dure 1 heure. Quelle capacité mémoire faut-il pour stocker cet enregistrement. Comparer avec l’espace mémoire disponible sur un CDROM. Commenter. Exercice 3. On peut considérer que la mémoire d’un ordinateur est constituée d’un certain nombre de cases repérées par leur adresse (qui est un nombre entier positif). (a) Dans un ordinateur « 32 bits » les adresses sont des nombres entiers positifs écrits sur 32 bits. Quelle quantité de mémoire peut-on adresser dans ce cas ? (b) Même question avec un ordinateur 64 bits, puis avec un ordinateur 32 bits utilisant l’extension PAE (c’est à dire autorisant 4 bits supplémentaires pour l’adressage). Exercice 4. Ces exemples sont à réaliser dans la fenêtre Shells de l’interface. (1) Tester les calculs : 2**60+1-2**60 et 2**60+1.0-2**60. Commenter. Essayer à nouveau avec la puissance 25 à la place de 60. À partir de quelle puissance le changement se produit-il ? (2) Saisir l’instruction x = 10**-9 puis répéter plusieurs fois (à la main) le couple d’instructions x = x**2 et print(x). Observation ? (3) Calculer 1 + 1/2 + 1/3 + 1/4 + 1/5p+ 1/6 puis faire calculer la même somme à l’envers. (4) On considère le polynôme x 2 −2 2x+2. Que vaut en théorie son discriminant ? Quelle valeur trouve-t-on en faisant les calculs avec P YTHON ? Exercice 5 La technique du bit de parité . On veut transmettre des données, constituées de nombres sur 7 bits, sur un canal de transmission pouvant éventuellement induire des erreurs. Pour les détecter, la technique du bit de parité consiste à ajouter à chaque groupe de 7 bits un bit supplémentaire (appelé bit de parité) choisi de sorte que le nombre total de 1 parmi les 8 bits soit pair. (a) On considère le nombre 84. Écrire ce nombre en binaire sur 7 bits. Quel est le bit de parité à ajouter pour la transmission ? (b) On reçoit le nombre 138. Écrire ce nombre en binaire sur 8 bits. La transmission comporte-t-elle une erreur ? (c) On reçoit le nombre 139. Écrire ce nombre en binaire sur 8 bits. Peut-on affirmer que la transmission a été effectuée sans erreur ? (d) On considère la fonction suivante : def f(n,p): s = 0 for k in range(p): s = s+n%10 n = n//10 return s et on donne également quelques exemples : print(f(403,3),f(123,3),f(12,3)) 7 6 3 print(f(403,2),f(123,2),f(12,2)) 3 5 3 Décrire ce que fait cette fonction. (e) En s’inspirant de la fonction f précédente, écrire une fonction bit_parite(n) qui calcule et renvoie le bit de parité associé au nombre n qui est un entier sur 7 bits (compris entre 0 et 127). (f) Écrire une fonction adjoindre_parite(n) qui reçoit un entier n sur 7 bits et renvoie l’entier sur 8 bits obtenu en lui adjoignant son bit de parité. (g) Écrire une fonction verifier_parite(n) qui reçoit un entier n sur 8 bits (compris entre 0 et 255) et renvoie 0 si le nombre de 1 dans son écriture est pair et 1 s’il est impair. Exercice 6 Quelques calculs en base 10 et en base 2. (a) Quel est le plus grand nombre que l’on peut écrire avec (au plus) p chiffres en base 10 ? (b) Quel est le plus petit nombre qui s’écrit avec exactement p chiffres en base 10 ? (c) Soit n un entier et p le nombre de chiffres dans l’écriture de n en base 10. Déterminer un encadrement de n à l’aide de p puis en déduire un encadrement de p à l’aide de ln(n). (d) Reprendre les questions précédentes en base 2. Corrections Ex 1. Prenons un livre de poche avec une soixantaine de caractères par ligne et une quarantaine de lignes par pages. On note c le nombre de caractères dont est constitué le livre et m l’espace mémoire nécessaire en Mo : kio = 1024 Mio = 1024*kio c = 60*40*200 print(c,c/Mio) 480000 0.457763671875 Ex 2. L’échantillonnage à 44.1 kHz signifie qu’il y a 44100 valeurs par seconde. Chaque valeur occupe 2 octets : # Durée de l’enregistrement en secondes : t = 3600 # Nombres de valeurs : n = t*44100 # Capacité mémoire m = n*2 print(m/Mio) 302.8106689453125 On trouve de l’ordre de 300 Mio, c’est à dire la moitié de la capacité mémoire d’un CDROM. Or les valeurs numériques de l’énoncé sont précisément celles utilisées pour l’enregistrement des CD audio. Ceci est cohérent car l’enregistrement effectué sur un CD audio est en stéréo. Ex 3. Une adresse stockée sur 32 bits peut prendre les valeurs entières de 0 à 232 − 1 : Gio = 1024*Mio print(2**32,2**32/Gio) 4294967296 4.0 Un ordinateur 32 bits peut adresser au plus 4 Gio de mémoire. De même : print(2**64/Gio) print(2**36/Gio) 17179869184.0 64.0 Ex 4. (a) Le premier calcul ne comporte que des nombres entiers, c’est un calcul exact. Le second calcul comporte des approximations. On trouve que le changement se produit à la puissance 53. (b) On arrive rapidement à 0 alors que x 2 , x 4 , etc. sont tous strictement positifs. (c) Les deux résultats sont différents, l’ordre dans lequel est effectué le calcul a un impact sur les approximations effectuées. p 2 (d) On trouve ∆ = 4 2 − 8 = 0 mais avec P YTHON le calcul ne donne pas 0 (mais une valeur très petite). Ex 5. Le nombre 84 s’écrit 1010100 en binaire. Cette écriture comporte un nombre impair de 1, il faut donc lui adjoindre un bit de parité égal à 1 pour la transmission. Le nombre 138 s’écrit 10001010 en binaire. Cette écriture comporte un nombre impair de 1 donc il y a eu une erreur durant la transmission. Le nombre 139 s’écrit 10001011. Cette écriture comporte un nombre pair de 1 mais on ne peut pas affirmer qu’il n’y a pas eu d’erreur durant la transmission. On peut cependant affirmer que soit la transmission est correcte, soit il y a eu au moins 2 bits changés. La fonction f calcule la somme des p chiffres de n en base 10, en partant de la droite dans l’écriture de n. On peut adapter cette fonction pour obtenir le bit de parité d’un nombre n de 7 bits. On calcule tout d’abord la somme s des chiffres de n en base 2 (on utilise donc des divisions euclidiennes par 2). Ensuite si cette somme est paire, le bit de parité est 0 et si elle est impaire le bit de parité est 1. Le bit de parité est donc le reste dans la division euclidienne de s par 2. def bit_parite(n): s = 0 for k in range(7): s = s+n%2 n = n//2 return s%2 print(bit_parite(84)) 1 Pour la fonction adjoindre_parite, on commence par calculer le bit de parité avec la fonction précédente puis on ajoute ce bit de parité au nombre n reçu en calculant n + 128b où b est le bit de parité : def adjoindre_parite(n): b = bit_parite(n) return n+128*b print(adjoindre_parite(84)) 212 Enfin, pour la fonction verifier_parite, il faut calculer la somme des chiffres de n en binaire sur 8 bits et renvoyer 0 si cette somme est paire et 1 si elle est impaire. def verifier_parite(n): s = 0 for k in range(8): s = s+n%2 n = n//2 return s%2 print(verifier_parite(138),verifier_parite(139)) 1 0 Ex 6. (a) Le plus grand nombre que l’on peut écrire avec au plus p chiffres en base 10 est : 99 · · · 9 = 10p − 1 p chiffres Par exemple le plus grand nombre qui s’écrit avec 3 chiffres en base 10 est 999 = 1000 − 1 = 103 − 1. (b) Le plus petit nombre qui s’écrit avec exactement p chiffres en base 10 est : 100 · · · 0 = 10p−1 p chiffres Par exemple le plus petit nombre qui s’écrit avec 3 chiffres en base 10 est 100 = 102 . (c) Si n s’écrit avec p chiffres en base 10, alors d’après ce qui précède 10p−1 É n É 10p − 1, ou encore : 10p−1 É n < 10p On applique la fonction ln (strictement croissante) : (p − 1) ln(10) É ln(n) < p ln(10) puis on divise par ln(10) (qui est strictement positif) : p −1 É ln(n) <p ln(10) On en déduit l’encadrement de p : ln(n) ln(n) <pÉ +1 ln(10) ln(10) (d) Dans le cas de la base 2 : • Le plus grand nombre qui s’écrit avec p chiffres en base 2 est 2p − 1 ; • Le plus petit nombre qui s’écrit avec exactement p chiffres en base 2 est 2p−1 ; • Si un entier n s’écrit avec exactement p chiffres en base 2, alors 2p−1 É n É 2p − 1 ou encore 2p−1 É n < 2p ; • En appliquant la fonction ln, on obtient (p − 1) ln(2) É ln(n) < p ln(2) et on en déduit : ln(n) ln(n) <pÉ +1 ln(2) ln(2)