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 :
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⁴
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 2¹
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
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
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.
u8 | u16 | u32 | u64 |
---|---|---|---|
0 à 2⁸=256 | 0 à 2¹⁶=65536 | 0 à 2³²=4294967296 | 0 à 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
i8 | i16 | i32 | i64 |
---|---|---|---|
-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 ! ;)