Περίληψη
Ένας ακέραιος του προγράμματος δεν είναι ακέραιος των μαθηματικών: είναι μια πεπερασμένη ακολουθία από bit, και με bit χωρούν ακριβώς διαφορετικές τιμές. Αυτό το μάθημα μελετά αυτή την αναπαράσταση και τις συνέπειές της. Διδάσκει πώς γράφεται ένας ακέραιος στη βάση 2 και στη βάση 16 και πώς ελέγχεται η γραφή του με τις προδιαγραφές μορφής {:b} και {:x}· παρουσιάζει τους ακέραιους τύπους της C++, το μέγεθός τους, που μετριέται με το sizeof, και το εύρος τιμών τους, που το βρίσκουμε με το std::numeric_limits· εξηγεί πώς αναπαρίστανται οι αρνητικοί με το συμπλήρωμα ως προς δύο και γιατί το εύρος τιμών δεν είναι συμμετρικό· διακρίνει τους προσημασμένους ακεραίους από τους μη προσημασμένους, και μελετά τι συμβαίνει όταν μια πράξη βγαίνει έξω από το εύρος τιμών: στους μη προσημασμένους το πρότυπο ορίζει το αποτέλεσμα, που είναι αριθμητική modulo · στους προσημασμένους δεν το ορίζει, και το πρόγραμμα μένει έξω από κάθε εγγύηση. Κλείνει με ένα κριτήριο για την επιλογή του τύπου κάθε δεδομένου.
Μαθησιακοί στόχοι
- Να μετατρέπετε ακεραίους ανάμεσα στις βάσεις 10, 2 και 16 και να ελέγχετε τη μετατροπή με τις προδιαγραφές μορφής
{:b}και{:x}. - Να υπολογίζετε το εύρος τιμών ενός ακεραίου bit, με πρόσημο και χωρίς πρόσημο, και να το ελέγχετε με το
std::numeric_limitsκαι τοsizeof. - Να εξηγείτε το συμπλήρωμα ως προς δύο και να γράφετε την αναπαράσταση ενός μικρού αρνητικού σε οκτώ bit.
- Να διακρίνετε την υπερχείλιση με πρόσημο, που είναι απροσδιόριστη συμπεριφορά, από την υπερχείλιση χωρίς πρόσημο, που είναι αριθμητική modulo , και να προβλέπετε το αποτέλεσμα της δεύτερης.
- Να επιλέγετε τον κατάλληλο ακέραιο τύπο για ένα δεδομένο σύμφωνα με το αναμενόμενο εύρος τιμών του, χρησιμοποιώντας τους τύπους σταθερού πλάτους της
<cstdint>όταν το πλάτος έχει σημασία.
Θεσιακά συστήματα αρίθμησης
Το μάθημα Μεταβλητές και μνήμη παρουσίασε τη μεταβλητή ως ένα κελί με όνομα, τύπο και τιμή. Όμως η μνήμη δεν αποθηκεύει δεκαδικά ψηφία: αποθηκεύει bit, καθένα από τα οποία έχει τιμή 0 ή 1, ομαδοποιημένα σε byte των οκτώ bit (το πρότυπο απαιτεί τουλάχιστον οκτώ· όλα τα σημερινά συστήματα χρησιμοποιούν ακριβώς οκτώ). Για να ξέρουμε ποιες τιμές μπορεί να πάρει μια ακέραια μεταβλητή πρέπει, επομένως, να ξέρουμε πώς γράφεται ένας αριθμός με δύο μόνο ψηφία, και αυτό ακριβώς κάνει ένα θεσιακό σύστημα αρίθμησης με βάση 2.
Σε ένα θεσιακό σύστημα αρίθμησης με βάση , κάθε ψηφίο αξίζει ανάλογα με τη θέση που κατέχει: το τελευταίο πολλαπλασιάζεται επί , το ψηφίο πριν από αυτό επί , το πριν από εκείνο επί , και ούτω καθεξής. Στη βάση 10, το σημαίνει . Στη βάση 2 τα ψηφία είναι 0 και 1, και τα βάρη είναι οι δυνάμεις του 2: Από αυτό έπεται ο κανόνας για τη μετάβαση από το δυαδικό στο δεκαδικό: προσθέτουμε τα βάρη των θέσεων όπου υπάρχει 1.
Το σχήμα διαβάζει τον συνδυασμό οκτώ bit 00101101. Πάνω από κάθε κελί βρίσκεται το βάρος του· τα ψηφία 1 ανάβουν ένα ένα, από αριστερά προς τα δεξιά, και η τιμή συσσωρεύει τα βάρη τους.
Απόδειξη
Οκτώ κελιά, όλα σβηστά: η τιμή είναι 0. Τα βάρη, από δεξιά προς τα αριστερά, είναι .
Το πρώτο 1 βρίσκεται στη θέση με βάρος 32: η συσσωρευμένη τιμή είναι 32.
Ακολουθεί εκείνο στη θέση με βάρος 8: .
Ύστερα, εκείνο στη θέση με βάρος 4: .
Το τελευταίο, στη θέση με βάρος 1: . Ο συνδυασμός
00101101αναπαριστά τον αριθμό 45.Ομαδοποιημένα ανά τέσσερα, τα bit δίνουν τα δεκαεξαδικά ψηφία: το
0010είναι 2 και το1101είναι 13, που στη βάση 16 γράφεταιd. Επομένως, το 45 γράφεται2dστη βάση 16.
Τον αντίστροφο δρόμο, από το δεκαδικό στο δυαδικό, τον διανύουμε με διαδοχικές διαιρέσεις: διαιρούμε τον αριθμό με το 2, σημειώνουμε το υπόλοιπο (0 ή 1) και επαναλαμβάνουμε με το πηλίκο ώσπου να φτάσουμε στο 0· τα υπόλοιπα, διαβασμένα από το τελευταίο προς το πρώτο, είναι τα δυαδικά ψηφία. Για το 45: , , , , , · διαβασμένα ανάποδα, τα υπόλοιπα δίνουν 101101, που με δύο μηδενικά στα αριστερά είναι ο συνδυασμός του σχήματος. Ο λόγος είναι ότι κάθε υπόλοιπο είναι το ψηφίο των μονάδων του αριθμού που διαιρείται, και κάθε πηλίκο είναι αυτός ο αριθμός μετατοπισμένος κατά μία θέση προς τα δεξιά. Η ίδια μέθοδος ισχύει για οποιαδήποτε βάση: για τη βάση 16 διαιρούμε με το 16, και τα υπόλοιπα από 10 έως 15 γράφονται με τα γράμματα a έως f.
Η βάση 16, ή δεκαεξαδικό σύστημα, υπάρχει για ευκολία: αφού , κάθε δεκαεξαδικό ψηφίο αντιστοιχεί ακριβώς σε τέσσερα bit, και ένα byte γράφεται με δύο ψηφία. Ένας αριθμός 32 bit πιάνει τριάντα δύο ψηφία στο δυαδικό, που διαβάζονται δύσκολα, και μόνο οκτώ στο δεκαεξαδικό, που μετατρέπονται σε δυαδικό χωρίς υπολογισμό, ψηφίο προς ψηφίο. Γι’ αυτό οι προγραμματιστές διαβάζουν τη μνήμη στο δεκαεξαδικό. Η μαθηματική θεμελίωση των θεσιακών συστημάτων μελετάται στον κύκλο μαθημάτων Άλγεβρα και γεωμετρία I, στο μάθημα «Θεσιακά συστήματα αρίθμησης».
Η C++ δέχεται ακεραίους γραμμένους απευθείας σε αυτές τις βάσεις: μια σταθερά (literal) που αρχίζει με 0b είναι στο δυαδικό, και μια που αρχίζει με 0x, στο δεκαεξαδικό. Μέσα σε οποιαδήποτε σταθερά μπορεί να μπει μια απόστροφος ως διαχωριστικό ψηφίων, που ο μεταγλωττιστής την αγνοεί και ο αναγνώστης την εκτιμά: 0b0010'1101, 1'000'000. Στην έξοδο, η προδιαγραφή μορφής {:b} γράφει έναν ακέραιο στο δυαδικό, η {:x} στο δεκαεξαδικό με πεζά και η {:X} με κεφαλαία· το σύμβολο # προτάσσει το πρόθεμα, και ένα πλάτος με ένα μηδέν μπροστά του γεμίζει με μηδενικά στα αριστερά.
#include <print>int main(){ const int decimal{45}; const int binary{0b0010'1101}; const int hexadecimal{0x2d}; std::println("{} {} {}", decimal, binary, hexadecimal); std::println("δυαδικό: {:b}", decimal); std::println("οκτώ bit: {:08b}", decimal); std::println("δεκαεξαδικό: {:x} {:X} {:#x}", decimal, decimal, decimal);}45 45 45δυαδικό: 101101οκτώ bit: 00101101δεκαεξαδικό: 2d 2D 0x2dΟι τρεις μεταβλητές έχουν την ίδια τιμή, γραμμένη σε τρεις βάσεις, και η πρώτη γραμμή της εξόδου το δείχνει: η βάση είναι ιδιότητα της γραφής, όχι του αριθμού. Η μνήμη αποθηκεύει και στις τρεις περιπτώσεις τον ίδιο συνδυασμό bit. Η προδιαγραφή {:b} παραλείπει τα μηδενικά στα αριστερά· η {:08b} συμπληρώνει οκτώ ψηφία.
Φόρτωση του περιεχομένου…
Ολοκληρώθηκε
Συνδεθείτε για να αποθηκεύσετε την πρόοδό σας