Vai al contenuto

Lezione 02 · Sistemi di numerazione

Cosa impari

  • la differenza tra sistemi di numerazione posizionali e non posizionali;
  • le basi usate in informatica: decimale, binaria, ottale, esadecimale;
  • a convertire un numero da qualsiasi base in base 10;
  • a convertire un numero decimale in binario: divisioni successive per la parte intera, moltiplicazioni successive per la parte frazionaria;
  • a passare da binario a ottale ed esadecimale (e viceversa) raggruppando i bit;
  • a fare somma, sottrazione, moltiplicazione e divisione in binario.

Un computer lavora solo con 0 e 1, noi siamo abituati alle cifre da 0 a 9. In questa lezione impari a passare da un sistema all'altro e a fare i conti direttamente in binario. Sono gli esercizi più frequenti dello scritto di teoria.

Sistemi posizionali e non posizionali

Un sistema di numerazione è un insieme di simboli (le cifre) e di regole che associano a ogni sequenza di cifre uno e un solo valore numerico.

  • Non posizionale: ogni simbolo vale sempre la stessa quantità, ovunque si trovi. Nel sistema romano L vale sempre 50.
  • Posizionale: il valore di una cifra dipende dalla sua posizione. In 1345 la cifra 5 vale 5 unità, il 4 vale 4 decine, il 3 tre centinaia, l'1 un migliaio.
Posizione 3 2 1 0
Cifra 1 3 4 5
Peso 10³ = 1000 10² = 100 10¹ = 10 10⁰ = 1

1345 = 1 × 1000 + 3 × 100 + 4 × 10 + 5 × 1

La regola generale

In un sistema posizionale con base (o radice) b, una cifra in posizione j ha peso bʲ. Le posizioni si contano da destra, partendo da 0, e la posizione 0 è quella subito a sinistra della virgola. Le cifre dopo la virgola hanno posizioni negative: −1, −2, …

Un numero con i cifre intere e k cifre frazionarie

c₍ᵢ₋₁₎ … c₁ c₀ , c₋₁ c₋₂ … c₋ₖ

vale:

x = c₍ᵢ₋₁₎ · bⁱ⁻¹ + … + c₁ · b¹ + c₀ · b⁰ + c₋₁ · b⁻¹ + c₋₂ · b⁻² + … + c₋ₖ · b⁻ᵏ

Due numeri reali in base 10 con 2 + 2 cifre

  • 00,13 = 0 · 10¹ + 0 · 10⁰ + 1 · 10⁻¹ + 3 · 10⁻² = 0,1 + 0,03
  • 10,40 = 1 · 10¹ + 0 · 10⁰ + 4 · 10⁻¹ + 0 · 10⁻² = 10 + 0,4

Le basi usate in informatica

In base b servono b simboli, per i valori da 0 a b − 1.

Base Nome Cifre
10 decimale 0 1 2 3 4 5 6 7 8 9
2 binaria 0 1
8 ottale 0 1 2 3 4 5 6 7
16 esadecimale 0 1 2 3 4 5 6 7 8 9 A B C D E F

In esadecimale le lettere valgono: A = 10, B = 11, C = 12, D = 13, E = 14, F = 15.

Come si scrive la base. Si racchiude il numero tra parentesi e si scrive la base in basso a destra:

(101111)₂ = (142)₅ = (47)₁₀

Segno meno, operatori e virgola si scrivono come in decimale. Gli zeri a sinistra si possono togliere, e anche quelli a destra della parte frazionaria: (00101,100)₂ = (101,1)₂.

Come si legge. Solo in decimale si legge "quarantasette". Negli altri sistemi si leggono le cifre una per una, dalla più pesante, dicendo la base: (142)₅ si legge "uno quattro due in base cinque".

Da qualsiasi base a base 10

Basta applicare la regola generale: moltiplica ogni cifra per il suo peso e somma.

Numero Calcolo Risultato
(101111)₂ 1·2⁵ + 0·2⁴ + 1·2³ + 1·2² + 1·2¹ + 1·2⁰ = 32 + 8 + 4 + 2 + 1 (47)₁₀
(142)₅ 1·5² + 4·5¹ + 2·5⁰ = 25 + 20 + 2 (47)₁₀
(47)₁₀ 4·10¹ + 7·10⁰ (47)₁₀

Il sistema binario

Il binario ha solo 2 simboli, quindi servono più cifre per scrivere lo stesso numero. Per avere almeno 10 configurazioni (come le cifre decimali) servono ⌈log₂ 10⌉ = 4 bit. In media un numero binario è circa 3,3 volte più lungo del corrispondente decimale.

Esempio svolto: (10101010)₂ in decimale

Scrivi i pesi sopra le cifre e somma solo quelli sotto cui c'è un 1.

Peso 2⁷ = 128 2⁶ = 64 2⁵ = 32 2⁴ = 16 2³ = 8 2² = 4 2¹ = 2 2⁰ = 1
Cifra 1 0 1 0 1 0 1 0
Contributo 128 0 32 0 8 0 2 0

128 + 32 + 8 + 2 = (170)₁₀

Altri esempi: (1001101)₂ = 64 + 8 + 4 + 1 = (77)₁₀; (111100)₂ = (60)₁₀; (10100001)₂ = (161)₁₀; (1100010100)₂ = (788)₁₀.

Verifica con Python (facoltativo). La funzione int(testo, base) converte una stringa di cifre in un numero decimale.

print(int('10101010', 2))   # da binario
print(int('142', 5))        # da base 5
print(int('17E', 16))       # da esadecimale
print(int('576', 8))        # da ottale

numero = input('Scrivi un numero binario: ')
print('In decimale vale', int(numero, 2))

Ottale ed esadecimale

Le stringhe di bit diventano presto lunghe e difficili da leggere. Ottale ed esadecimale servono a scriverle in forma compatta. Il passaggio da e verso il binario è immediato perché 8 = 2³ e 16 = 2⁴: una cifra ottale corrisponde a 3 bit, una cifra esadecimale a 4 bit.

Ottale Binario Esadecimale Binario Esadecimale Binario
0 000 0 0000 8 1000
1 001 1 0001 9 1001
2 010 2 0010 A 1010
3 011 3 0011 B 1011
4 100 4 0100 C 1100
5 101 5 0101 D 1101
6 110 6 0110 E 1110
7 111 7 0111 F 1111
  • Binario → ottale: raggruppa i bit a gruppi di tre, partendo da destra (dal bit di peso minore). Se l'ultimo gruppo a sinistra è incompleto, aggiungi zeri a sinistra. Sostituisci ogni gruppo con la sua cifra.
  • Ottale → binario: sostituisci ogni cifra ottale con i suoi 3 bit.
  • Binario → esadecimale ed esadecimale → binario: stessa cosa, con gruppi di quattro.

Esempio svolto: (101111110)₂ in ottale e in esadecimale

Ottale, gruppi di 3 da destra:

Gruppi 101 111 110
Cifra ottale 5 7 6

(101111110)₂ = (576)₈

Esadecimale, gruppi di 4 da destra (il primo gruppo 1 diventa 0001):

Gruppi 0001 0111 1110
Cifra esadecimale 1 7 E

(101111110)₂ = (17E)₁₆

Da decimale a binario

Il metodo ha due passi.

  1. Separa la parte intera dalla parte frazionaria. Ad esempio 382,25 = 382 + 0,25.
  2. Converti le due parti con due algoritmi diversi e poi rimettile insieme.

Parte intera: divisioni successive per 2

Dividi il numero per 2 e annota quoziente e resto. Poi dividi il quoziente per 2, e così via, finché il quoziente diventa 0. I resti, letti dall'ultimo al primo, sono le cifre binarie.

  • Il resto della prima divisione è il bit meno significativo (LSB, a destra).
  • Il resto dell'ultima divisione è il bit più significativo (MSB, a sinistra).
Perché funziona

La parte intera si scrive d = cᵢ·2ⁱ + … + c₂·2² + c₁·2¹ + c₀. Tutti i termini tranne c₀ sono multipli di 2. Quindi dividendo d per 2 il resto è c₀ e il quoziente è cᵢ·2ⁱ⁻¹ + … + c₂·2¹ + c₁. Dividendo di nuovo per 2 il resto è c₁, e così via: ogni divisione "stacca" la cifra successiva.

Esempio svolto: (382)₁₀ in binario

Divisione Quoziente Resto
382 : 2 191 0 ← LSB
191 : 2 95 1
95 : 2 47 1
47 : 2 23 1
23 : 2 11 1
11 : 2 5 1
5 : 2 2 1
2 : 2 1 0
1 : 2 0 1 ← MSB

Leggendo i resti dal basso verso l'alto: (382)₁₀ = (101111110)₂.

Controllo: 256 + 64 + 32 + 16 + 8 + 4 + 2 = 382.

Parte frazionaria: moltiplicazioni successive per 2

Moltiplica la parte frazionaria per 2. La parte intera del prodotto (0 oppure 1) è la cifra binaria successiva. Poi scarta quella parte intera e moltiplica di nuovo per 2 solo la parte frazionaria. Le cifre si leggono nell'ordine in cui le ottieni, dall'alto verso il basso.

Ti fermi quando:

  • la parte frazionaria diventa 0: la conversione è esatta;
  • la parte frazionaria si ripete: il numero binario è periodico;
  • hai ottenuto il numero di cifre richiesto: la rappresentazione è approssimata.
Perché funziona

La parte frazionaria si scrive f = c₋₁·2⁻¹ + c₋₂·2⁻² + c₋₃·2⁻³ + … Moltiplicando per 2 ottieni c₋₁ + c₋₂·2⁻¹ + c₋₃·2⁻² + … Il primo termine c₋₁ è un intero (0 o 1) e finisce a sinistra della virgola; tutto il resto è minore di 1. Quindi la parte intera del prodotto è proprio c₋₁, e la nuova parte frazionaria contiene le cifre successive.

Esempio svolto: (382,25)₁₀ in binario

La parte intera l'hai già convertita: (382)₁₀ = (101111110)₂. Ora la parte frazionaria 0,25:

Frazione × 2 Parte intera
0,25 0,50 0
0,50 1,00 1

La parte frazionaria è 0: conversione esatta. (0,25)₁₀ = (0,01)₂.

Quindi (382,25)₁₀ = (101111110,01)₂.

Esempio svolto: (82,84)₁₀ in binario, con 8 cifre dopo la virgola

Parte intera 82:

Divisione Quoziente Resto
82 : 2 41 0
41 : 2 20 1
20 : 2 10 0
10 : 2 5 0
5 : 2 2 1
2 : 2 1 0
1 : 2 0 1

Resti dal basso: (82)₁₀ = (1010010)₂.

Parte frazionaria 0,84:

Frazione × 2 Parte intera
0,84 1,68 1
0,68 1,36 1
0,36 0,72 0
0,72 1,44 1
0,44 0,88 0
0,88 1,76 1
0,76 1,52 1
0,52 1,04 1
0,04 … …

Dopo 8 cifre la parte frazionaria (0,04) non è ancora zero: ci fermiamo e il risultato è approssimato.

(82,84)₁₀ ≈ (1010010,11010111)₂

Un numero decimale semplice può non esserlo in binario

0,1 in decimale ha una sola cifra, ma in binario è periodico: (0,1)₁₀ = (0,0001100110011…)₂. Il calcolatore deve tagliarlo, quindi lo memorizza in modo approssimato. Per questo in Python 0.1 + 0.2 dà 0.30000000000000004.

Da decimale a ottale o esadecimale

Il modo più semplice: converti prima in binario, poi raggruppa i bit.

Numero Binario Gruppi da 4 Esadecimale
(84)₁₀ (1010100)₂ 0101 0100 (54)₁₆
(382)₁₀ (101111110)₂ 0001 0111 1110 (17E)₁₆

In alternativa puoi usare le divisioni successive per 16 (o per 8): i resti sono le cifre. Ad esempio 382 : 16 = 23 resto 14 (E); 23 : 16 = 1 resto 7; 1 : 16 = 0 resto 1. Dal basso: (17E)₁₆.

Verifica con Python (facoltativo). Il programma rifà le divisioni successive e stampa la tabella. Poi controlla il risultato con bin(), oct() e hex() (il prefisso 0b, 0o o 0x indica la base).

n = int(input('Numero intero da convertire: '))
originale = n
cifre = ''
print('Quoziente  Resto')
while n > 0:
    resto = n % 2
    n = n // 2
    print(f'{n:9}  {resto:5}')
    cifre = str(resto) + cifre   # il nuovo resto va a SINISTRA
print('In binario:', cifre)
print('Controllo:', bin(originale), oct(originale), hex(originale))

E questo rifà le moltiplicazioni successive per la parte frazionaria, fermandosi dopo un numero massimo di cifre:

f = float(input('Parte frazionaria (es. 0.25): '))
max_cifre = int(input('Quante cifre al massimo? '))
cifre = ''
conta = 0
while f != 0 and conta < max_cifre:
    f = f * 2
    if f >= 1:
        cifre = cifre + '1'
        f = f - 1
    else:
        cifre = cifre + '0'
    conta = conta + 1
print('In binario: 0,' + cifre)
if f != 0:
    print('Risultato approssimato: la parte frazionaria non si è annullata')

Prova con 0.25 (esatto), con 0.84 e 8 cifre, e con 0.1 e 12 cifre (periodico).

Tool · Cambio di base

Risolvi prima l'esercizio a mano, poi controllalo qui: il tool mostra le stesse tabelle di divisioni e moltiplicazioni successive, lo sviluppo posizionale e il metodo veloce con i gruppi di bit. Funziona con qualsiasi base da 2 a 36.

Operazioni aritmetiche in binario

Somma, sottrazione, moltiplicazione e divisione funzionano come in decimale. Cambiano solo le tabelline, che sono molto più corte:

a b a + b a − b a × b
0 0 0 0 0
0 1 1 1 con prestito di 1 0
1 0 1 1 0
1 1 0 con riporto di 1 0 1

Ricorda: in binario 1 + 1 = (10)₂, cioè "scrivo 0 e riporto 1". E 1 + 1 + 1 = (11)₂, cioè "scrivo 1 e riporto 1".

Addizione

Si parte da destra e il riporto si propaga a sinistra, come in decimale.

Esempio svolto: (1001010)₂ + (11011)₂

2⁶ 2⁵ 2⁴ 2³ 2² 2¹ 2⁰
Riporti 1 1 1
1 0 0 1 0 1 0
+ 1 1 0 1 1
= 1 1 0 0 1 0 1

Colonna per colonna da destra: 0+1 = 1; 1+1 = 0 riporto 1; 0+0+1 = 1; 1+1 = 0 riporto 1; 0+1+1 = 0 riporto 1; 0+0+1 = 1; 1+0 = 1.

Risultato (1100101)₂. Controllo in decimale: 74 + 27 = 101 = (1100101)₂.

Sottrazione

Quando devi fare 0 − 1 chiedi un prestito alla prima cifra 1 a sinistra, come in decimale. Il prestito vale 2 nella colonna che lo riceve, quindi 0 − 1 diventa (10)₂ − 1 = 1. La cifra che ha prestato diventa 0, e gli eventuali 0 intermedi diventano 1.

Esempio svolto: (101)₂ − (010)₂

2² 2¹ 2⁰
1 0 1
− 0 1 0
= 0 1 1
  • Colonna 2⁰: 1 − 0 = 1.
  • Colonna 2¹: 0 − 1 non si può. Prendi in prestito dalla colonna 2²: l'1 diventa 0 e la colonna 2¹ diventa (10)₂ = 2. Ora 2 − 1 = 1.
  • Colonna 2²: 0 − 0 = 0.

Risultato (011)₂ = (11)₂. Controllo: 5 − 2 = 3.

Esempio più lungo: (10100001)₂ − (1010101)₂ = (1001100)₂, cioè 161 − 85 = 76.

Moltiplicazione

È la più facile: ogni cifra del moltiplicatore è 0 o 1, quindi ogni prodotto parziale è tutto zeri oppure una copia del moltiplicando, spostata a sinistra. Alla fine sommi i prodotti parziali.

Esempio svolto: (10100001)₂ × (101)₂

2⁹ 2⁸ 2⁷ 2⁶ 2⁵ 2⁴ 2³ 2² 2¹ 2⁰
1 0 1 0 0 0 0 1
× 1 0 1
1 0 1 0 0 0 0 1
+ 0 0 0 0 0 0 0 0
+ 1 0 1 0 0 0 0 1
= 1 1 0 0 1 0 0 1 0 1

Risultato (1100100101)₂. Controllo: 161 × 5 = 805.

Divisione

Si procede come la divisione in colonna decimale, ma ogni cifra del quoziente può essere solo 0 o 1: ti chiedi soltanto se il divisore "ci sta" nella parte di dividendo che stai considerando. Ad esempio (111)₂ : (101)₂, cioè 7 : 5: il divisore ci sta una volta, quoziente 1 e resto (10)₂ = 2.

Esempio svolto: (10001)₂ : (11)₂, cioè 17 : 3

Prendi le cifre del dividendo una alla volta, da sinistra.

Passo Parte considerata 11 ci sta? Cifra del quoziente Resto parziale
1 1 no 0 1
2 10 no 0 10
3 100 sì: 100 − 11 = 1 1 1
4 10 (abbasso lo 0) no 0 10
5 101 (abbasso l'1) sì: 101 − 11 = 10 1 10

Quoziente (00101)₂ = (101)₂ = 5, resto (10)₂ = 2. Controllo: 3 × 5 + 2 = 17.

Verifica con Python (facoltativo): converti in decimale, fai l'operazione e riconverti.

a = int('1001010', 2)
b = int('11011', 2)
print('somma:', bin(a + b), '=', a + b)
print('differenza:', bin(int('10100001', 2) - int('1010101', 2)))
print('prodotto:', bin(int('10100001', 2) * int('101', 2)))
print('quoziente e resto:', bin(17 // 3), bin(17 % 3))

Tool · Somme e sottrazioni in colonna

Scrivi i due numeri in bit e scegli l'operazione: il tool mostra la riga dei riporti (o dei prestiti) come nelle tabelle qui sopra.

Errori frequenti negli esercizi

Errore Perché è sbagliato Come si corregge
Leggere i resti dall'alto verso il basso il primo resto è il bit meno significativo scrivi i resti dall'ultimo al primo
Fermarsi quando il quoziente è 1 manca l'ultima cifra (l'MSB) continua finché il quoziente è 0
Leggere al contrario le cifre della parte frazionaria la prima moltiplicazione dà la cifra subito dopo la virgola per la parte frazionaria leggi dall'alto verso il basso
Moltiplicare per 2 anche la parte intera del prodotto la parte intera è già una cifra del risultato togli la parte intera, moltiplica solo la frazione
Raggruppare i bit partendo da sinistra i gruppi vengono sbagliati per la parte intera raggruppa da destra, aggiungendo zeri a sinistra
Scrivere 1 + 1 = 2 in binario in binario la cifra 2 non esiste 1 + 1 = 0 con riporto 1
Dimenticare l'ultimo riporto il risultato ha una cifra in meno se resta un riporto, scrivilo come nuova cifra a sinistra

Esercizi

Esercizio 1 · Dal binario alle altre basi. Converti (110101)₂ in decimale, in ottale e in esadecimale.

Soluzione

Decimale:

Peso 32 16 8 4 2 1
Cifra 1 1 0 1 0 1

32 + 16 + 4 + 1 = (53)₁₀

Ottale, gruppi di 3 da destra: 110 | 101 → 6 | 5 → (65)₈

Esadecimale, gruppi di 4 da destra: 0011 | 0101 → 3 | 5 → (35)₁₆

Controllo: 6 × 8 + 5 = 53 e 3 × 16 + 5 = 53.

Esercizio 2 · Un numero con la virgola. Converti (45,375)₁₀ in binario, poi scrivi la parte intera in esadecimale.

Soluzione

Parte intera 45:

Divisione Quoziente Resto
45 : 2 22 1
22 : 2 11 0
11 : 2 5 1
5 : 2 2 1
2 : 2 1 0
1 : 2 0 1

Resti dal basso: (45)₁₀ = (101101)₂.

Parte frazionaria 0,375:

Frazione × 2 Parte intera
0,375 0,75 0
0,75 1,5 1
0,5 1,0 1

La frazione si annulla: (0,375)₁₀ = (0,011)₂, esatto.

Risultato: (45,375)₁₀ = (101101,011)₂.

Esadecimale della parte intera: 0010 | 1101 → 2 | D → (2D)₁₆. Controllo: 2 × 16 + 13 = 45.

Esercizio 3 · Conto in binario (come allo scritto). Calcola 85 + 98 così: converti i due numeri in binario, fai la somma in binario, riconverti il risultato in decimale e verifica.

Soluzione

Conversioni con le divisioni successive: (85)₁₀ = (1010101)₂ e (98)₁₀ = (1100010)₂.

Somma:

2⁷ 2⁶ 2⁵ 2⁴ 2³ 2² 2¹ 2⁰
Riporti 1
1 0 1 0 1 0 1
+ 1 1 0 0 0 1 0
= 1 0 1 1 0 1 1 1

Solo nella colonna 2⁶ c'è 1 + 1 = 0 con riporto 1, che diventa la nuova cifra 2⁷.

Riconversione: (10110111)₂ = 128 + 32 + 16 + 4 + 2 + 1 = 183.

Verifica: 85 + 98 = 183. ✓

Verifica