Aller au contenu

Représentation de La Mémoire

Explication

Avant de partir tête baissé dans le language Rust, on va d’abord s’intéresser à comment fonctionne la mémoire d’un ordinateur.

Et oui parce qu’avec Rust on peut choisir le type qu’on va donner à une valeur numérique et pour comprendre comment on fait pour choisir le bon type il va falloir comprendre comment fonctionne la mémoire.

Tu le sais sans doute mais pour un ordinateur tout n’est que 0 et 1 et la mémoire ne fait pas exception à la rèlge.

Donc quand on va stocker une valeur en mémoire, elle va être directement stockée sous forme de 0 et de 1. Autrement dit notre valeur va être transformer en nombre binaire.

Mais Comment on fait pour transformer un nombre en binaire ?

C’est ce qu’on va voir ici.

Premièrement, une case qui va contenir un 0 ou un 1 est ce qu’on appelle un bit.

Un ensemble de 8 bits c’est ce qu’on appelle un octet en français ou un byte en anglais, oui ça porte à confusion parce que ça ressemble beaucoup à bit raison pour laquelle je préfère le terme octet.

En fonction de la taille du nombre qu’on veut stocker on va utiliser plus ou moins de bits.

Les entiers non signés

Voyons ensemble le type u8 de Rust

  • le u est l’abréviation de unsigned, qui veut dire “non signé”, c’est à dire sans signe + ou - devant le nombre, tout ça pour dire un nombre forcément positif ou nul.
  • Le 8 c’est le nombre de bits de la variable, donc ici on utilise 8 bits pour écrire notre nombre.

Prenons comme exemple le nombre 19 qu’on va écrire en u8 :

Pour commencer on va écrire 8 puissances de 2 en partant de 0, de la droite vers la gauche, ce qui nous donne :

Puissance de 2

Maintenant le but du jeu va être de trouver la puissance de 2 qui se rapproche le plus de 19 sans le dépasser!

On essaye par tatonnement et on se rend compte que c’est 4 qui nous donne 2⁴ = 16

On va donc mettre un 1 sous 2⁴ 16

Maintenant qu’on a écrit 16 il nous reste encore à écrire 3 pour arriver à 19 (19 - 16 = 3)

On recommence en cherchant la puissance de 2 la plus proche de 3 qui ne dépasse pas 3

On trouve que c’est 1 qui donne 2¹ = 2

On va donc mettre un 1 sous 18

Et maintenant on continue puisqu’on a déjà écrit 16+2=18 il nous reste encore à écrire 1 pour arriver à 19 ce qui correspond à 2⁰ donc on met un 1 sous 2⁰ = 1 19

Voilà maintenant qu’on a écrit notre nombre on va mettre des 0 dans les cases vide comme ça pour avoir notre nombre en binaire sur 8bits 19

Ainsi 19 s’écrit en u8 : 00001011

Donc quand tu crée en Rust une variable u8 qui vaut 19, elle sera stockée en mémoire sous la forme 0000 1011. ( L’espace est là juste pour la lisibilité)

Maintenant si tu veux écrire le même nombre sur 16 bits par exemple il suffit de rajouter des zéros avant le résultat obtenu :

Voici donc 19 en u16 : 0000 0000 0000 1011

En fonction du nombre de bits utilisés on va pouvoir écrire des nombres plus ou moins grands.

Voici les nombres que sont capable de stockés chaque type unsigned en Rust.

u8u16u32u64
0 à 2⁸=2560 à 2¹⁶=655360 à 2³²=42949672960 à 2⁶⁴=1,84x10¹⁹

Maintenant tu es en mesure de choisir quel est le type qui s’adapte le mieux à ta valeur, imagine que veuilles stocker un mois de l’année de 1 à 12 tu va utiliser un u8 en revanche si tu veux stocker l’année d’un évènement tu vas utiliser un u16.

La seule chose qu’on a pas encore vu c’est comment stocker des valeurs négatives et c’est ce qu’on va voir tout de suite avec les entiers signés.

Les entiers signés

Les entiers signés fonctionnent globalement de la même façon que les entiers non signés mais ils doivent stocker le signe du nombre en question.

Au final, si on prend un nombre sur 8bits, il ne reste plus que 7bits pour stocker le nombre en question puisque 1bit sera utilisé pour stocker le signe du nombre.

Imaginons qu’on veuille écrire -45 sous la forme d’un i8 (un entier signé sur 8bits), voici les différentes étapes pour y parvenir:

  • Ecrire le nombre sous la forme positive (donc 45 ici) : 0010 1101
  • Inverser Chaque bit (les 0 deviennent de 1 et inversement) : 1101 0010
  • Ajouter 1 à notre nombre ce qui donne : 1101 0011
i8i16i32i64
-2⁷ à 2⁷-1-2¹⁵ à 2¹⁵-1-2³¹ à 2³¹-1-2⁶³ à 2⁶³-1

Tu peux voir que la capacité d’un entier signé de n bits est de -2^n à 2^n-1

Un point important ici est de remarquer que selon le type que l’on donne à une valeur (u8 ou i8) sa représentation en mémoire sera différente, par exemple le nombre 1101 0011 correspond à -45 si il est stocké en i8 et 227 si il est stocké en u8.

C’est Rust qui sait comment décoder chaque valeur en fonction de son type, en règle général si tu n’as pas besoin de valeurs négative il vaut mieux utiliser un entier non signé.

Conclusion

Tu sais maintenant comment Rust utilise la mémoire pour stocker des entiers de différentes tailles, signés et non signés.

Tu vas désormais pouvoir choisir le meilleur type possible pour tes variables !

Bravo ! ;)