Η C#, όπως πολλές στατικά τυπισμένες γλώσσες, παρέχει αρκετούς τύπους που αναπαριστούν ακέραιους αριθμούς, ο καθένας με το δικό του εύρος τιμών. Στο κάτω άκρο, ο τύπος sbyte έχει ελάχιστη τιμή -128 και μέγιστη τιμή 127. Όπως σε όλους τους ακέραιους τύπους, αυτές οι τιμές είναι διαθέσιμες ως <type>.MinValue και <type>.MaxValue. Στο πάνω άκρο, ο τύπος long έχει ελάχιστη τιμή -9.223.372.036.854.775.808 και μέγιστη τιμή 9.223.372.036.854.775.807. Στη μέση βρίσκονται οι τύποι short και int.
Τα εύρη καθορίζονται από το πλάτος αποθήκευσης του τύπου, όπως το δεσμεύει το σύστημα. Για παράδειγμα, ένα byte χρησιμοποιεί 8 bit και ένα long χρησιμοποιεί 64 bit.
Κάθε ένας από τους παραπάνω τύπους συνδυάζεται με έναν αντίστοιχο ανυπόγραφο τύπο: sbyte/byte, short/ushort, int/uint και long/ulong. Σε όλες τις περιπτώσεις, το εύρος των τιμών είναι από το 0 έως το αρνητικό του προσημασμένου μεγίστου επί 2 συν 1.
| Type | Width | 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 |
Μια μεταβλητή (ή μια παράσταση) ενός τύπου μπορεί εύκολα να μετατραπεί σε άλλον τύπο. Για παράδειγμα, σε μια εντολή ανάθεσης, αν ο τύπος της τιμής που ανατίθεται (lhs) εξασφαλίζει ότι η τιμή θα βρίσκεται μέσα στο εύρος του τύπου στον οποίο γίνεται η ανάθεση (rhs), τότε αρκεί μια απλή ανάθεση:
uint ui = uint.MaxValue;
ulong ul = ui; // no problem
Από την άλλη, αν το εύρος του τύπου από τον οποίο γίνεται η ανάθεση δεν είναι υποσύνολο του εύρους τιμών του δέκτη, τότε απαιτείται μια πράξη cast, (), ακόμη και αν η συγκεκριμένη τιμή βρίσκεται μέσα στο εύρος του δέκτη:
short s = 42;
uint ui = (uint)s;
Η κλάση BitConverter παρέχει έναν βολικό τρόπο μετατροπής ακέραιων τύπων από και προς πίνακες byte.
Η εργασία συνεχίζεται στο έργο του τηλεχειριζόμενου αυτοκινήτου. Το εύρος ζώνης στο σύστημα τηλεμετρίας είναι περιορισμένο και σου έχει ζητηθεί να υλοποιήσεις ένα πρωτόκολλο μηνυμάτων για τη μετάδοση δεδομένων τηλεμετρίας.
Τα δεδομένα μεταδίδονται μέσα σε έναν buffer (πίνακας byte). Όταν αποστέλλονται ακέραιοι, το μέγεθος του buffer μειώνεται με την εφαρμογή του πρωτοκόλλου που περιγράφεται παρακάτω.
Κάθε τιμή πρέπει να αναπαρίσταται στον μικρότερο δυνατό ακέραιο τύπο (οι τύποι byte και sbyte δεν περιλαμβάνονται, καθώς η εξοικονόμηση θα ήταν αμελητέα):
| Από | Έως | Τύπος |
|---|---|---|
| 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 |
Η τιμή πρέπει να μετατρέπεται στον κατάλληλο αριθμό byte για τον τύπο που της έχει ανατεθεί. Ο πλήρης buffer περιλαμβάνει ένα byte που υποδεικνύει τον αριθμό των πρόσθετων byte στον buffer (byte προθέματος), ακολουθούμενο από τα byte που περιέχουν τον ακέραιο (byte ωφέλιμου φορτίου).
Κάποιοι από τους τύπους χρησιμοποιούν τον ίδιο αριθμό byte (π.χ. οι τύποι uint και int). Κανονικά, θα είχαν το ίδιο byte προθέματος, αλλά αυτό θα έκανε την αποκωδικοποίηση προβληματική. Για να αντιμετωπιστεί αυτό, το πρωτόκολλο εισάγει ένα μικρό τρικ: για τους προσημασμένους τύπους, η τιμή του byte προθέματος είναι 256 μείον τον αριθμό των πρόσθετων byte στον buffer.
Μόνο το byte προθέματος και ο αριθμός των επόμενων byte που υποδεικνύονται από το byte προθέματος θα αποσταλούν στην επικοινωνία. Εσωτερικά χρησιμοποιείται ένας buffer 9 byte (με μηδενικά στο τέλος, όταν χρειάζεται) τόσο από τις ρουτίνες αποστολής όσο και από τις ρουτίνες λήψης.
Υλοποίησε τη στατική μέθοδο TelemetryBuffer.ToBuffer() για να κωδικοποιήσεις έναν buffer παίρνοντας την παράμετρο που περνιέται στη μέθοδο.
// 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 };
Υλοποίησε τη στατική μέθοδο TelemetryBuffer.FromBuffer() για να αποκωδικοποιήσεις τον buffer που έλαβες και να επιστρέψεις την τιμή με τη μορφή long.
TelemetryBuffer.FromBuffer(new byte[] {0xfc, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0 })
// => 2147483647
Αν το byte προθέματος έχει μη αναμενόμενη τιμή, τότε θα πρέπει να επιστραφεί το 0.
Γράψου στο Exercism για να μάθεις και να κατακτήσεις C# με 62 έννοιες178 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.