En

Entiers en Rust

1 exercice

À propos de Entiers

Les entiers sont des nombres sans partie fractionnaire ni décimale. Ils sont représentés dans la machine par une suite de bits binaires.

Les entiers peuvent être signés ou non. Le fait d'être signé signifie que l'on réserve l'un des bits du nombre pour indiquer si ce nombre est négatif ou non.

Tous les entiers ont une largeur de bits, c'est-à-dire le nombre de bits qui composent ce nombre. Cela détermine la valeur maximale que ce type entier peut représenter.

Par exemple, l'un des types entiers les plus courants est un u8 : un entier non signé sur 8 bits. Tu reconnaîtras peut-être ce type comme un seul octet. Sa valeur minimale est 0 et sa valeur maximale est 255.

Rust propose 12 types entiers primitifs, répartis par largeur de bits et par signe :

Non signé Signé
u8 i8
u16 i16
u32 i32
u64 i64
u128 i128
usize isize

La largeur de bits d'un entier est toujours indiquée par le nombre qui suit le u ou le i. usize et isize sont spéciaux : leur largeur est celle d'un pointeur sur la machine cible. Cela signifie que sur une architecture 64 bits, usize et isize font 64 bits de large, alors que sur une architecture 32 bits, ils font 32 bits de large.

Lequel utiliser ?

En général, si tu as simplement besoin de représenter un nombre, utilise un i32 : 32 bits offrent une plage suffisamment large pour qu'un dépassement soit relativement improbable, et les nombres signés réservent moins de surprises que les nombres non signés. i32 est équivalent à un long en C, ou à un int en Java. Si tu utilises un littéral numérique sans annoter explicitement le type, il prendra par défaut le type i32.

Si tu travailles avec des données binaires, le plus simple est de travailler avec des octets : &[u8] ou Vec<u8>.

Rust utilise usize pour la taille et l'indexation des collections. En effet, un ordinateur ne peut théoriquement adresser que usize::MAX octets de mémoire, donc aucune collection en mémoire plus grande n'est possible. Par conséquent, usize peut être utile si tu travailles beaucoup avec des collections.

Si tes données ne tiennent pas dans un entier 32 bits, envisage de passer à un entier 64 ou 128 bits. Si tes données ne tiennent pas dans un entier 128 bits, tu peux alors utiliser un type grand entier, comme celui fourni par num-bigint.

Les entiers 16 bits ne sont pas très courants, mais ils peuvent être utiles lorsqu'on cible certains microcontrôleurs.

Si tu sais qu'il n'existe aucun cas négatif valide pour ton application, il vaut mieux utiliser un entier non signé plutôt qu'un entier signé. Le comptage en est un bon exemple.

Convertis un entier en un autre

Rust n'effectue aucune conversion numérique implicite. Si tu dois convertir d'un type entier à un autre, il existe deux stratégies de base : le mot-clé as, et les traits From et TryFrom.

Utiliser le mot-clé as est simple : expr as Type. Cependant, il y a un certain nombre de pièges et de subtilités à garder en tête lorsque tu utilises les conversions avec as.

La conversion à base de traits est un peu plus lourde, mais plus sûre : les traits de conversion ne sont implémentés que là où la conversion est sûre. Par exemple, i32 implémente From<u8>, From<u16>, From<i8>, et From<i16> : toute valeur représentable par l'un de ces types est garantie d'être représentable dans un i32. Elle peut s'utiliser comme i32::from(expr), ou expr.into(), où expr correspond à l'un de ces types. i32 implémente aussi TryFrom<u32>, TryFrom<u64>, TryFrom<u128>, TryFrom<usize>, TryFrom<i64>, TryFrom<i128>, et TryFrom<isize>. Selon la valeur, ces conversions vont explicitement soit réussir, soit produire un dépassement. Pour les utiliser, tu devras importer le trait std::convert::TryFrom ou std::convert::TryInto selon le cas, puis utiliser i32::try_from(expr) ou expr.try_into(), où expr correspond à un type approprié.

La conversion à base de traits est généralement préférée à la conversion avec as, en particulier lorsqu'on passe d'un type plus large à un type plus étroit. La conversion à base de traits est très légèrement plus coûteuse que la conversion avec as : utiliser as pour des raisons de performance n'en vaut pas la peine, sauf dans une boucle extrêmement intensive.

Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet