C#, comme beaucoup de langages à typage statique, fournit un certain nombre de types qui représentent des entiers, chacun avec sa propre plage de valeurs. À l'extrémité basse, le type sbyte a une valeur minimale de -128 et une valeur maximale de 127. Comme pour tous les types entiers, ces valeurs sont disponibles sous la forme <type>.MinValue et <type>.MaxValue. À l'extrémité haute, le type long a une valeur minimale de -9 223 372 036 854 775 808 et une valeur maximale de 9 223 372 036 854 775 807. Entre les deux se trouvent les types short et int.
Les plages sont déterminées par la largeur de stockage du type, telle qu'allouée par le système. Par exemple, un byte utilise 8 bits et un long utilise 64 bits.
Chacun des types ci-dessus est associé à un équivalent non signé : sbyte/byte, short/ushort, int/uint et long/ulong. Dans tous les cas, la plage de valeurs va de 0 au maximum signé négatif multiplié par 2, plus 1.
| Type | Largeur | Minimum | Maximum |
|---|---|---|---|
| sbyte | 8 bit | -128 | +127 |
| short | 16 bit | -32_768 | +32_767 |
| int | 32 bit | -2_147_483_648 | +2_147_483_647 |
| long | 64 bit | -9_223_372_036_854_775_808 | +9_223_372_036_854_775_807 |
| byte | 8 bit | 0 | +255 |
| ushort | 16 bit | 0 | +65_535 |
| uint | 32 bit | 0 | +4_294_967_295 |
| ulong | 64 bit | 0 | +18_446_744_073_709_551_615 |
Une variable (ou une expression) d'un type peut facilement être convertie en un autre. Par exemple, dans une affectation, si le type de la valeur affectée (lhs) garantit que cette valeur se situera dans la plage du type de destination (rhs), alors une simple affectation suffit :
uint ui = uint.MaxValue;
ulong ul = ui; // no problem
En revanche, si la plage du type source n'est pas un sous-ensemble de la plage de valeurs du type de destination, une opération de cast, (), est nécessaire, même si la valeur particulière se trouve dans la plage du type de destination :
short s = 42;
uint ui = (uint)s;
La classe BitConverter offre un moyen pratique de convertir des types entiers vers des tableaux d'octets et inversement.
Le travail se poursuit sur le projet de voiture télécommandée. La bande passante du système de télémétrie est limitée et on t'a demandé d'implémenter un protocole de messages pour transmettre les données de télémétrie.
Les données sont transmises dans un tampon (un tableau d'octets). Lorsque des entiers sont envoyés, la taille du tampon est réduite grâce au protocole décrit ci-dessous.
Chaque valeur doit être représentée dans le plus petit type entier possible (les types byte et sbyte ne sont pas inclus, car le gain serait négligeable) :
| De | À | Type |
|---|---|---|
| 4_294_967_296 | 9_223_372_036_854_775_807 | long |
| 2_147_483_648 | 4_294_967_295 | uint |
| 65_536 | 2_147_483_647 | int |
| 0 | 65_535 | ushort |
| -32_768 | -1 | short |
| -2_147_483_648 | -32_769 | int |
| -9_223_372_036_854_775_808 | -2_147_483_649 | long |
La valeur doit être convertie dans le nombre d'octets approprié à son type. Le tampon complet comprend un octet indiquant le nombre d'octets supplémentaires qu'il contient (octet de préfixe), suivi des octets qui portent l'entier (octets de charge utile).
Certains types utilisent un nombre identique d'octets (par exemple les types uint et int). Normalement, ils auraient le même octet de préfixe, mais cela rendrait le décodage problématique. Pour y remédier, le protocole introduit une petite astuce : pour les types signés, la valeur de leur octet de préfixe est 256 moins le nombre d'octets supplémentaires dans le tampon.
Seuls l'octet de préfixe et le nombre d'octets suivants indiqués par celui-ci sont envoyés lors de la communication. En interne, un tampon de 9 octets est utilisé (avec des zéros de remplissage si nécessaire), aussi bien par les routines d'envoi que de réception.
Implémente la méthode statique TelemetryBuffer.ToBuffer() pour encoder un tampon à partir du paramètre passé à la méthode.
// Type: ushort, bytes: 2, signed: no, prefix byte: 2
TelemetryBuffer.ToBuffer(5)
// => {0x2, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
// Type: int, bytes: 4, signed: yes, prefix byte: 256 - 4
TelemetryBuffer.ToBuffer(Int32.MaxValue)
// => {0xfc, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0 };
Implémente la méthode statique TelemetryBuffer.FromBuffer() pour décoder le tampon reçu et renvoyer la valeur sous la forme d'un long.
TelemetryBuffer.FromBuffer(new byte[] {0xfc, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0 })
// => 2147483647
Si la valeur de l'octet de préfixe est inattendue, il faut renvoyer 0.
Inscris-toi sur Exercism pour apprendre et maîtriser C# avec 62 concepts178 exercices, et un vrai mentorat humain, le tout gratuitement.