Μετάβαση στο περιεχόμενο

Αναπαράσταση δεδομένων

Δυαδικό και δεκαεξαδικό, αρνητικοί αριθμοί, χαρακτήρες και Unicode.

45 λεπτά

Θα μάθεις να

  1. Να μετατρέπεις αριθμούς ανάμεσα στο δεκαδικό, το δυαδικό και το δεκαεξαδικό σύστημα.
  2. Να γράφεις αρνητικούς ακέραιους σε 8 bit με συμπλήρωμα ως προς 2 και να ξέρεις το εύρος τους.
  3. Να εξηγείς πώς κωδικοποιούνται οι χαρακτήρες στο ASCII και στο Unicode.
  4. Να υπολογίζεις πόσα bytes πιάνει ένα κείμενο στο UTF-8, με ελληνικά και λατινικά γράμματα.

Bit και byte

Ο υπολογιστής αποθηκεύει τα πάντα ως σειρές από bit (binary digit), δηλαδή ψηφία που παίρνουν μόνο δύο τιμές, 00 και 11. Οκτώ bit κάνουν ένα byte. Με kk bit φτιάχνονται 2k2^k διαφορετικοί συνδυασμοί: ένα byte έχει 28=2562^8 = 256.

Τρία συστήματα αρίθμησης

Όλα είναι θεσιακά: η αξία ενός ψηφίου εξαρτάται από τη θέση του. Στο δεκαδικό κάθε θέση αξίζει δέκα φορές την προηγούμενη, στο δυαδικό δύο, στο δεκαεξαδικό δεκαέξι. Το δεκαεξαδικό χρειάζεται δεκαέξι ψηφία, οπότε μετά το 99 χρησιμοποιεί τα γράμματα A έως F για τις τιμές 1010 έως 1515.

ΔεκαδικόΔυαδικόΔεκαεξαδικό
0000000
5501015
9910019
10101010A
13131101D
15151111F

Από δυαδικό σε δεκαδικό: πρόσθεσε τις δυνάμεις του 22 που αντιστοιχούν στους άσσους.

1011012=1⋅25+0⋅24+1⋅23+1⋅22+0⋅21+1⋅20=32+8+4+1=4510101101_2 = 1 \cdot 2^5 + 0 \cdot 2^4 + 1 \cdot 2^3 + 1 \cdot 2^2 + 0 \cdot 2^1 + 1 \cdot 2^0 = 32 + 8 + 4 + 1 = 45_{10}

Από δεκαδικό σε δυαδικό: διαίρεσε διαδοχικά με το 22 και κράτα τα υπόλοιπα. Το αποτέλεσμα διαβάζεται από κάτω προς τα πάνω.

ΔιαίρεσηΠηλίκοΥπόλοιπο
45:245 : 2222211
22:222 : 2111100
11:211 : 25511
5:25 : 22211
2:22 : 21100
1:21 : 20011

Από κάτω προς τα πάνω: 101101.

Ανάμεσα σε δυαδικό και δεκαεξαδικό η μετατροπή είναι σχεδόν δωρεάν, γιατί 16=2416 = 2^4: κάθε δεκαεξαδικό ψηφίο αντιστοιχεί σε ακριβώς τέσσερα bit. Χωρίζεις σε τετράδες από τα δεξιά: 0010 1101 γίνεται 2D. Γι' αυτό το δεκαεξαδικό χρησιμοποιείται παντού στην πληροφορική: ένα byte γράφεται με δύο ψηφία αντί για οκτώ. Τα χρώματα στις ιστοσελίδες, όπως #FF8800, είναι τρία bytes σε δεκαεξαδικό: κόκκινο 255255, πράσινο 136136, μπλε 00.

Αρνητικοί αριθμοί: συμπλήρωμα ως προς 2

Η πρώτη ιδέα είναι να αφιερώσεις ένα bit στο πρόσημο. Έχει όμως δύο προβλήματα: υπάρχουν δύο μηδενικά, το +0+0 και το −0-0, και η πρόσθεση θέλει ειδικούς κανόνες για τα πρόσημα. Οι υπολογιστές χρησιμοποιούν αντί γι' αυτό το συμπλήρωμα ως προς 2 (two's complement).

Για να γράψεις το −x-x σε 88 bit:

  1. Γράψε το xx σε 88 bit.
  2. Αντέστρεψε κάθε bit: τα 00 γίνονται 11 και τα 11 γίνονται 00.
  3. Πρόσθεσε 11.
ΒήμαΓια το −45-45
το 4545 σε 88 bit00101101
αντιστροφή11010010
συν 1111010011

Το αριστερότερο bit λειτουργεί ως bit προσήμου: 00 για μη αρνητικούς, 11 για αρνητικούς. Το μεγάλο πλεονέκτημα φαίνεται στην πρόσθεση:

  00101101    (+45)
+ 11010011    (-45)
----------
1 00000000    το ένατο bit δεν χωράει στα 8 και απορρίπτεται

Το αποτέλεσμα είναι 00, με την ίδια πρόσθεση που κάνει η ΑΛΜ για τους θετικούς. Ένα κύκλωμα αρκεί και για τα δύο.

Χαρακτήρες: ASCII και Unicode

Για να γραφτεί κείμενο, κάθε χαρακτήρας αντιστοιχίζεται σε έναν αριθμό. Ο πρώτος διαδεδομένος πίνακας ήταν το ASCII (1963): 77 bit, 128128 χαρακτήρες, με τα λατινικά γράμματα, τα ψηφία, τα σημεία στίξης και μερικούς χαρακτήρες ελέγχου.

ΧαρακτήραςΚωδικός ASCIIΔυαδικόΔεκαεξαδικό
048480011000030
A65650100000141
a97970110000161

Τα κεφαλαία και τα πεζά απέχουν ακριβώς 3232, δηλαδή ένα μόνο bit. Τα ελληνικά δεν χωρούσαν στο ASCII, και για χρόνια χρησιμοποιούνταν πίνακες 88 bit ειδικά για τα ελληνικά. Ένα αρχείο γραμμένο με έναν πίνακα και διαβασμένο με άλλον έβγαζε ακατάληπτα σύμβολα.

Η λύση ήρθε με το Unicode: ένας ενιαίος κατάλογος που δίνει σε κάθε χαρακτήρα κάθε γραφής έναν αριθμό, το σημείο κώδικα (code point). Το «A» είναι U+0041, το «Γ» είναι U+0393, το «α» είναι U+03B1. Ο κατάλογος έχει χώρο για πάνω από ένα εκατομμύριο χαρακτήρες.

Το Unicode λέει ποιος αριθμός. Το UTF-8 λέει πώς γράφεται σε bytes, και χρησιμοποιεί μεταβλητό μήκος:

ΧαρακτήρεςBytes στο UTF-8Παράδειγμα
οι 128128 του ASCII11«A» → 41
ελληνικά, κυριλλικά, αραβικά και άλλα22«Γ» → CE 93
τα περισσότερα υπόλοιπα, π.χ. κινεζικά, το σύμβολο του ευρώ33«€» → E2 82 AC
emoji και σπάνιοι χαρακτήρες44😀 → F0 9F 98 80

Το έξυπνο στο UTF-8 είναι ότι ένα κείμενο γραμμένο μόνο σε ASCII είναι ήδη έγκυρο UTF-8, byte προς byte. Γι' αυτό επικράτησε: σήμερα η συντριπτική πλειονότητα των ιστοσελίδων είναι σε UTF-8.

for s in ["A", "Γ", "€", "Γεια", "Hi"]:
    print(s, len(s), len(s.encode("utf-8")))

print(ord("A"), chr(97), hex(ord("Γ")))
print(bin(45), hex(45), int("101101", 2))
print(format(-45 & 0xFF, "08b"))  # το -45 σε 8 bit, συμπλήρωμα ως προς 2

Η πρώτη επανάληψη τυπώνει για το «Γεια» 4 χαρακτήρες και 8 bytes, για το «Hi» 2 και 2. Οι τρεις τελευταίες γραμμές τυπώνουν 65 a 0x393, 0b101101 0x2d 45 και 11010011.

Λυμένα παραδείγματα

Παράδειγμα 1

Γράψε το 20010200_{10} στο δυαδικό και στο δεκαεξαδικό.

Δοκίμασέ το πρώτα. Μετά δες τη λύση.

Παράδειγμα 2

Γράψε το −20-20 σε 88 bit με συμπλήρωμα ως προς 2 και έλεγξε το αποτέλεσμα.

Δοκίμασέ το πρώτα. Μετά δες τη λύση.

Παράδειγμα 3

Πόσα bytes πιάνει στο UTF-8 το κείμενο «Καλημέρα!»;

Δοκίμασέ το πρώτα. Μετά δες τη λύση.

Ασκήσεις

Πρώτα ερωτήσεις με επιλογές: διαλέγεις, πατάς «Έλεγξε» και μαθαίνεις αμέσως αν το βρήκες και γιατί. Στο τέλος, λίγες ασκήσεις χωρίς επιλογές — εκεί κρύβεται μόνο η απάντηση.

Πολλαπλή επιλογήΆσκηση 1 από 14
Ποια είναι η δεκαδική τιμή του δυαδικού 110101;

Τα κατάφερες;

  • Να μετατρέπεις αριθμούς ανάμεσα στο δεκαδικό, το δυαδικό και το δεκαεξαδικό σύστημα.
  • Να γράφεις αρνητικούς ακέραιους σε 8 bit με συμπλήρωμα ως προς 2 και να ξέρεις το εύρος τους.
  • Να εξηγείς πώς κωδικοποιούνται οι χαρακτήρες στο ASCII και στο Unicode.
  • Να υπολογίζεις πόσα bytes πιάνει ένα κείμενο στο UTF-8, με ελληνικά και λατινικά γράμματα.

Λύσε τις ασκήσεις πιο πάνω και θα δεις εδώ πού στέκεσαι.