Rappresentazione binaria dell’informazione Mauro Bianco – Al mondo ci sono 10 categorie di persone: quelle che conoscono la rappresentazione binaria e quelle che non la conoscono Contents 1 Rappresentazione binaria dei numeri naturali: la notazione posizionale 1 2 Numeri Binari 4 3 Conversioni binario-decimale e decimale-binario 3.1 Conversione decimale→binario . . . . . . . . . . . . . . . . . . . 3.2 Conversione binario→decimale . . . . . . . . . . . . . . . . . . . 4 5 6 4 Numeri esadecimali e ottali 8 5 Rappresentazione binaria dei 5.1 Bit di segno e magnitudo . 5.2 Complemento a 1 . . . . . . 5.3 Complemento a 2 . . . . . . 5.4 Eccesso-N . . . . . . . . . . numeri . . . . . . . . . . . . . . . . . . . . negativi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 9 10 11 12 6 Rappresentazione binaria dei numeri reali 14 6.1 Somma e prodotto di numeri in virgola mobile . . . . . . . . . . 15 7 Rappresentazione binaria delle stringhe Nota 1 16 : Le parti delimitate da ”***” sono da considerarsi facoltative. Rappresentazione binaria dei numeri naturali: la notazione posizionale Con una sequenza di n bit possiamo individuare 2n entità diverse, quindi anche i numeri interi da 0 a 2n−1 . In linea di principio l’associazione tra numeri e le 1 sequenze di bit può essere arbitraria, ma se cosı̀ fosse le operazioni aritmetiche sarebbero di difficile realizzazione in hardware. Per realizzare la somma, ad esempio, ci sarebbe bisogno di una mappa tra gli operandi e i risultati, ad esempio per calcolare 8+5=13 si devono mappare gli operandi e il risultato a delle sequenze di bit, ad esempio 100110+01101=0010. Quello di cui abbiamo bisogno è un algoritmo, il più possibile indipendente dagli operandi, per calcolare il risultato di una operazione. Per risolvere il problema ci viene incontro la notazione posizionale, inventata in India, trasmessa al mondo arabo e infine giunta in Europa in un lungo processo conclusosi nel XIV-XV secolo. È interessante sapere che il termine “algoritmo” deriva dal nome di Abu Ja’far Muhammad ibn Musa al-Khwarizmi (c.a. 780 - c.a. 850), autore del libro Algoritmi de numero Indorum (la versione araba è andata perduta) sull’uso della notazione posizionale per eseguire calcoli tra numeri. Per creare una notazione posizionale si deve scegliere una base b e b cifre c0 , . . . cb−1 che rappresentano rispettivamente i numeri da 0 a b − 1. Un generico numero x sarà poi scritto come sequenza di cifre an an−1 . . . a1 a0 , con ai ∈ {c0 , . . . , cb−1 }, che rappresenta il numero x= n X a i bi i=0 Si dice in questo caso che an an−1 . . . a1 a0 è la rappresentazione in base b del numero x. Per evitare confusione si indica questo fatto con x = (an an−1 . . . a1 a0 )b . Ad esempio il numero 346110 è il numero 3 · 103 + 4 · 102 + 6 · 10 + 1. Il fatto che stiamo usando la base 10 in questo esempio può portare a confusione. Facciamo un esempio con base 5. Dovremmo usare quindi le cifre da 0 a 4. La sequenza (341)5 rappresenta il numero (3 · 25 + 4 · 5 + 1)10 = (75 + 20 + 1)10 = (96)10 . La base più piccola che si può usare è la base 2 (perché la base 1 non funziona?). In questo caso le cifre che si possono usare sono 0 e 1 ma il principio è esattamente lo stesso. Dimostriamo un piccolo teorema: dati un numero x, una base b e le cifre c0 , . . . cb−1 , esiste una sola sequenza an an−1 . . . a1 a0 che rappresenta il numero x in base b. Utilizziamo l’induzione: se n = 1, allora il teorema vale. Supponiamo sia vero per n = k − 1. Dimostriamolo valido anche per n = k. x= k X a i bi = i=0 da cui si deriva che y = x − a k bk = k−1 X a i bi + a k bk , i=0 k X i=0 a i bi = k−1 X a i bi . i=0 Essendo y un numero rappresentabile con k cifre, la sua rappresentazione in base b è unica. Si ha quindi che se, per ipotesi, esistesse ān 6= an tale che 2 x = y + ak bk = y + āk bk . Si ravvede subito una contraddizione, in quanto si deduce che deve essere ān = an L’algoritmo per la somma di due numeri in base b diventa quindi il seguente: sia an an−1 . . . a1 a0 il primo numero e dn dn−1 . . . d1 d0 il secondo. Sia sn sn−1 . . . s1 s0 il risultato. Si imposti r0 = 0. Partendo dalla cifra più a sinistra si calcolino iterativamente ri+1 e si che soddisfano la seguente equazione: ai + di + ri = ri+1 b + si Essendo r0 uguale a zero, per induzione, si vede che deve essere ri+1 ≤ 1. Si ha infatti che ri ≤ 1 (per l’ipotesi induttiva) e ai + di + ri ≤ cb−1 + cb−1 + 1 ≤ b − 1 + b − 1 + 1 ≤ b + (b − 1) = (1cb−1 )b . Le stesse considerazioni fatte per i numeri interi possono essere fatte anche per i numeri razionali. Se si indica con un punto la separazione tra la parte intera e quella frazionaria, il generico numero x può essere scritto come x= n X a i bi + i=0 m X a−i b−i = an an−1 · · · a1 a0 .a−1 a−2 · · · a−m+1 a−m i=1 L’algoritmo di somma, in questo caso, rimane sostanzialmente identico a prima, solo che si richiede che i numeri da sommare vengano allineati al punto decimale e le cifre mancanti dell’uno o dell’altro vengano impostate a zero: s6 0 d5 s5 0 d4 s4 a2 d3 s3 a1 d1 s1 a0 d0 s0 . . . a−1 d−1 s−1 0 d−2 s−2 + = Analoghi algoritmi esistono per le altre operazioni elementari, che sono solo una generalizzazione delle analoghe operazioni insegnate alle scuole elementari con una base implicitamente pari a 1010 . Nel seguito, numeri la cui l’indicazione della base a pedice è omessa, a meno che non sia chiaro dal contesto, si riferiscono a numeri in base 10 10 . Esercizi: 1. Si calcoli 3234 + 1024 . 2. Si provi con altre basi e altri valori. 3. Come si esprime bi in base b per un generico i? 4. Si trovi l’algoritmo per il prodotto di due numeri in base b. 5. Si trovi l’algoritmo per la differenza di due numeri in base b. 3 2 Numeri Binari I numeri binari sono i numeri espressi in notazione posizionale in base 2. Su questi numeri possiamo applicare gli algoritmi di somma e sottrazione, prodotto e divisione in modo del tutto analogo ai numeri in base 10, l’unica differenza risiede nella nostra poca dimestichezza con questi numeri. Nel caso dei numeri in base dieci, ad esempio, noi conosciamo “a memoria” i risultati della somma di due cifre (1+1, 9+4, 7+3, etc.). Conoscendo questa informazione possiamo eseguire la somma di due numeri in base 10. Come visto nel caso generico si devono calcolare ri+1 e si che soddisfano ai + di + ri = ri+1 b + si . Nel caso di numeri binari, si deve ricordare la seguente tabella per la somma di due cifre: ai + di + ri si ri+1 Commento 0+0+0 0 0 0+0+0=0 0+1+0 1 0 0+1+0=1=0·2+1 1+0+0 1 0 1+0+0=1=0·2+1 1+1+0 0 1 1 + 1 + 0 = 210 = 102 = 1 · 2 + 0 0+0+1 1 0 0+0+1=0·2+1 0+1+1 0 1 0 + 1 + 1 = 210 = 102 = 1 · 2 + 0 1+0+1 0 1 1 + 0 + 1 = 210 = 102 = 1 · 2 + 0 1+1+1 1 1 1 + 1 + 1 = 310 = 112 = 1 · 2 + 1 Ad esempio si sommino i numeri binari (100110010) 2 e (10111011)2 : Riporto 0 0 0 1 1 0 0 1 0 Op1 1 0 0 1 1 0 0 1 0 + Op2 1 0 1 1 1 0 1 1 = Risultato 1 1 1 1 0 1 1 0 1 I numeri binari qui illustrati sono detti numeri Pn binari puri, in quanto il valore rappresentato è quello espresso dalla formula i=0 ai 2i . Questo per distinguerli da altre rappresentazioni che, come vedremo, non conservano questa proprietà. Per manipolare i numeri binari, anche a livello elementare, è utile saper fare le somme (e anche le differenze) tra numeri binari. Esercizi: 1. Si sommino 1010112 e 1101112 . 2. Si calcoli la differenza tra 1101112 e 1010112 e si verifichi la correttezza del calcolo. 3 Conversioni binario-decimale e decimale-binario Come si può passare da una notazione posizionale in base b a una in base b0 ? La risposta è contenuta nelle relazioni scritte nella precedente sezione. In questa sezione esplicitiamo le tecniche di conversione per passare dalla notazione decimale a quella binaria e viceversa nel caso di numeri interi. Prima di iniziare è utile fare qualche osservazione di carattere generale. 4 Moltiplicare per b un numero intero x espresso in base b, significa spostare le cifre di x di unaPposizione verso sinistra e inserire uno zero a destra. Si ha n infatti che, se x = i=0 ai bi , x·b=b n X a i bi = n X ai bi+1 = ai−1 bi + 0 · b0 . i=1 i=0 i=0 n+1 X Ad esempio 340710 · 1010 = 3407010 e, analogamente, 11010110102 · 210 = 11010110102 · 102 = 110101101002 In modo del tutto analogo, dividere per b un numero x espresso in base b, significa spostare le cifre di x di una posizione verso destra e spostare Pn la cifra più a destra a destra del punto decimale. Si ha infatti che, se x = i=0 ai bi , n−1 n−1 n n X X a0 x 1 X i X i−1 ai+1 bi + . ai+1 bi = ai b = ai b = = b b i=0 b i=0 i=−1 i=0 1101011012 10 = Si ricordi che ab0 < 1. Ad esempio 3407 1010 = 340.710 e, analogamente, 210 11010110.12 Se siamo interessati solo ai numeri interi, la parte frazionaria viene ignorata e viene conservata solo la parte intera (indicata con parte bassa di x e scritta bxc, ovvero il più grande numero intero minore o uguale a x). $ n % $ n % $ n−1 % n−1 jxk X X X 1X i i−1 i = ai b = ai b = ai+1 b = ai+1 bi . b b i=0 i=0 i=−1 i=0 k j k j 1101011012 10 = 340 e, analogamente, = 110101102 Ad esempio 3407 10 1010 210 Un importante corollario di queste osservazioni è che il resto della divisione per b, è uguale all’ultima cifra del numero. Si ha infatti che x− jxk b b= n X i=0 a i bi − b n−1 X ai+1 bi = n X a i bi − i=0 i=0 = n X i=0 3.1 n−1 X ai+1 bi+1 = i=0 a i bi − n X a i bi = a 0 (1) i=1 Conversione decimale→binario Utilizzando l’equazione (1) abbiamo un algoritmo per trovare le cifre di un numero in base b: basta dividere ripetutamente il numero per la base e prendere il resto della divisione. Nel caso in cui la base sia 2, questa operazione risulta particolarmente semplice. Il resto della divisione per 2 di un numero è infatti 0 se il numero è pari e 1 se il numero è dispari, e questa è l’ultima cifra del numero in no- 5 tazione binaria. Facciamo un esempio: convertiamo il numero 485 10 in binario: Numero Cifra Commento 485 1 485 è dispari 485/2=242 0 242 è pari 242/2=121 1 dispari 121/2=60 0 pari 60/2=30 0 pari 30/2=15 1 dispari 15/2=7 1 dispari 7/2=3 1 dispari 3/2=1 1 dispari 1/2=0 0 pari 0/2=0 0 pari .. .. .. . . . Ricordando che la cifra che esce dal calcolo del resto della divisione è la cifra più a destra del numero che rimane da convertire, si ha che 485 10 = 1111001012 (gli zeri a sinistra possono essere ignorati). 3.2 Conversione binario→decimale Per convertire numeri binari in base 10 si possono usare due metodi: il primo fa affidamento a una tabella di potenze di due, mentre il secondo è l’inverso del metodo visto per convertire i numeri decimali in binario. Il primo metodo si basa sulla definizione: si sommano le varie potenze di due che compongono il numero dato. Vediamolo con un esempio: 111100101 2 = 28 + 27 + 26 + 25 + 22 + 20 = 256 + 128 + 64 + 32 + 4 + 1 = 485. Si tratta qui di ricordare o consultare una tabella con i valori delle potenze di due e sommare quelle corrispondenti alle cifre “1” del numero dato. Questo metodo funziona molto bene per numeri piccoli, per i quali è facile ricordare le potenze di due e eseguire la somma a mano. Mentre può non essere inusuale per un’esperto ricordare la prime 17 potenze di 2 (da 0 a 16), anche il semplice numero 485 richiede un certo sforzo per l’esecuzione della somma di un numero di termini pari al numero di cifre “1” nel numero binario. Il secondo metodo si base sull’osservazione che, per i < n, (an · · · ai )b · b = (an · · · ai+1 )b + ai (basta applicare le formule viste all’inizio di questa sezione), e applicare il ragionamento iterativamente. Più in dettaglio (an )b (an an−1 )b = = an (an )b · b + an−1 (an an−1 an−2 )b (an an−1 an−2 an−3 )b .. . = = (an an−1 )b · b + an−2 (an an−1 an−2 )b · b + an−3 .. . (2) 6 Vediamo un esempio con il solito a sinistra Cifra Operazione Numero 1 1 1 1 1·2+1 3 1 3*2+1 7 1 0 0 1 0 1 7*2+1 15*2+0 30*2+0 60*2+1 121*2+0 242*2+1 15 30 60 121 242 485 numero 111100101 2 . Partendo dal bit più Commento inizio delle iterazioni moltiplico il numero precedente per due e sommo la cifra attuale Si noti il parallelo con la tabella della pagina precedente Esercizi: 1. Si convertano in decimale i seguenti numeri • • • • 325 334 1233 32016 2. Si convertano i seguenti numeri decimali in base 5 • 102310 • 23410 • 543210 3. Si convertino in binario i seguenti numeri decimali: • • • • 3210 6410 75310 320110 4. Si convertino in decimale i seguenti numeri binari. • • • • 1010112 1101112 1000002 100101011001102 5. Di quante cifre binarie sarà costituito il numero 1056? Come si può dirlo senza effettuare la conversione? (Suggerimento: qual è il massimo intero rappresentabile con n cifre binarie?) 7 4 Numeri esadecimali e ottali Due modi molti usati per rappresentare i numeri binari in modo sintetico sono le rappresentazioni ottali e esadecimali, ovverro rappresentare i numeri i base, rispettivamente, 8 (23 ) e 16 24 . Deriviamo la rappresentazioni in ottale di un numero binario di n cifre dove n è multiplo di tre1 : x= n−1 X n 3 −1 i ai 2 = 2 j = 0 a3i+j 2 3i+j i=0 i=0 n 3 −1 = n 3 −1 XX X i 2 = X 23i i=0 1 0 8 (a3i+2 · 2 + a3i+1 · 2 + a3i+0 · 2 ) = i=0 X j = 02 a3i+j 23i+j = n 3 −1 X (a3i+2 a3i+1 a3i+0 )2 8i i=0 Dato un numero binario a n cifre, la notazione ottale si ricava raggruppando a tre a tre le cifre binarie e sostituiendone i valori rappresentati. Ad esempio il numero (110010011001)2 deve essere raggruppato nel modo seguente (110 | 010 | 011 | 001)2 = (6231)8 Per quanto riguarda i numeri in base 16 il ragionamento è analogo al precedente. L’unica difficoltà è data dal fatto che la base 16 richiede 16 cifre. Nella notazione numerica utilizzata normalmente le cifre sono solo 10, quindi ne servono altre 6. Per convenzione si è deciso di utilizzare le lettere da A a F . Le cifre sono quindi le seguenti: 0 1 2 3 ... 9 A B C D E F Cifra Valore 0 1 2 3 . . . 9 10 11 12 13 14 15 Esercizi: 1. Si convertino in ottale e in esadecimale i seguenti numeri binari: • 1001100110112 • 100100111012 • 10011012 2. Si convertino in binario i seguenti numeri ottali: • 101108 • 34568 • 7008 • Si convertino in binario i seguenti numeri esadecimali: – 1011016 – 345616 1 Se n non è multiplo di tre è sufficiente aggiungere degli zeri a sinistra fino a avere un numero di cifre multiplo di tre 8 – 0F 3A16 • Si convertano in decimale i seguenti numeri ottali e esadecimali – – – – 3A016 C1A016 17628 32348 • Si convertano in ottale e eadecimale i seguenti numeri decimali – 234410 – 1000010 – 65710 5 Rappresentazione binaria dei numeri negativi La totalità dei calcolatori digitali esistenti possono “comprendere” solo due simboli: “0” e “1”. In più i dati (nel nostro caso i numeri naturali e interi) sono memorizzati in parole di lunghezza fissa, ovvero sequenze di un numero finito e fissato a priori di bit. Numeri tipicamente utilizzati sono 8 (in questo caso di parla di byte), 16 (half-word), 32 (word) e 64 (long-word) bit. Solo “byte” è un termine universalmente accettato per indicare una parola di 8 bit, mentre le altre indicazioni dipendono dal tipo di calcolatore che si sta considerando. Nel corso saranno utilizzate le diciture sopra indicate, anche se sempre seguite dalla specifica del numero di bit a cui si fa riferimento tranne nel caso del byte. Le considerazioni fatte nella sezione precedente rimangono valide per i numeri negativi se si adottano le convenzioni utilizzate comunemente nell’algebra, ovvero di utilizzare il simbolo “-” per indicare i numeri negativi. Nei calcolatori però questo non è possibile, come abbiamo accennato qui sopra. Alcune soluzioni a questo problema sono date di seguito. Prima di iniziare però è utile precisare alcune notazioni utilizzate. Si consideri una parola di 8 bit (1 byte). Il numero (00101001) 2 rappresenta il numero (41)10 . I due “0” a sinistra sono indicati per esplicitare il fatto che la parola è di 8 bit e che quella è la sequenza di bit memorizzata nel calcolatore. I bit vengono numerati da destra a sinistra partendo da zero a indicare l’esponente applicato alla base. Il bit più a sinistra è detto “Most Significant Bit” (bit più significativo, MSB), mentre quello più a destra “Least Significant Bit” (bit meno significativo, LSB). Nella tabella seguente un semplice esempio: bit 0 0 1 0 1 0 0 1 indici 7 6 5 4 3 2 1 0 MSB LSB 5.1 Bit di segno e magnitudo La più intuitiva soluzione al problema della rappresentazione dei numeri negativi è l’utilizzo del bit di segno. In questo caso il bit più significativo della parola sarà 9 “0” per indicare “+” e “1” per indicare “−”. È importante notare che in questo caso il bit più significativo non è più utilizzato per rappresentare il numero ma ne indica solo il segno. Pn−2 Se la parola utilizzata è di n bit, il massimo numero rappresentabile è i=0 2i = 2n−1 −1. Questo sistema ha due controindicazioni: 1. Esistono due rappresentazioni dello zero. Per una parola a 8 bit si ha ad esempio 0 = 00000000 = 10000000 = −0. 2. I circuiti che devono eseguire le operazioni devono essere replicati più volte per gestire i casi di numeri positivi e negativi. 5.2 Complemento a 1 Con questo sistema, il numero −x (x può essere esso negativo) viene rappresentato invertendo tutti i bit della parola che lo rappresenta, il che equivale a dire che i bit a zero diventano 1 e quelli a 1 diventano zero. Nel caso del numero P 4110 (001010012 ), −4110 verrà rappresentato dalla sequenza 11010110. n Se x = i=0 ai 2i , l’operazione di complemento a 1 corrisponde a sostituire la generica cifra ai con 1 − ai . In formule n X i=0 i (1 − ai )2 = n X i=0 i 2 − n X ai 2i = (2n − 1) − x i=0 Consideriamo parole di tre bit, la tabella successiva mostra i valori numerici assegnati alle parole se viene applicato il metodo del complemento a 1: 000 0 I numeri positivi sono rappresentati come numeri binari puri 001 1 I numeri positivi hanno il LSB a 0 010 2 011 3 100 -3 I numeri negativi hanno il MSB a 1 101 -2 Provate a ottenere queste rappresentazioni a partire dai numeri positivi 110 -1 111 -0 Si noti che esistono anche qui due rappresentazioni dello zero. Se applichiamo l’algoritmo della somma per i numeri binari a 1 e -1 nella tabella qui sopra, vediamo che il risultato è la sequenza 111, che rappresenta -0=0. Se sommiamo 1 a 000 otteniamo 001, che è corretto. Proviamo però a sommare 1 a 111 con l’algoritmo di somma: otteniamo 1000. Avendo solo 3 bit per memorizzare il numero otteniamo un overflow e il risultato ottenuto (se non si prendono adeguati provvedimenti, è 000, che è sbagliato!). Lo stesso problema si ottiene sommando -2 e -1. Si ha infatti che 1012 + 1102 = 1011. Le tre cifre meno significative darebbero la sequenza 011, ovvero +3. Come nel caso precedente, abbiamo due rappresentazioni per lo zero e dobbiamo ricorrere a circuiterie complicate per eseguire le operazioni elementari, in grado cioè di eseguire l’algoritmo giusto in dipendenza del segno degli operandi. 10 5.3 Complemento a 2 Per risolvere il problema si ricorre al complemento a 2, che si ottiene (a) complementando a 1, (b) sommando 1 al risultato e (c) considerando solo gli n bit partendo da destra, dove n è la lunghezza della parola utilizzata. Usando 3 bit si ottiene la seguente tabella: 000 0 I numeri positivi sono rappresentati come puri numeri binari 001 1 I numeri positivi hanno il LSB a 0 010 2 011 3 100 -4 I numeri negativi hanno il MSB a 1 101 -3 Provate a ottenete queste rappresentazioni a partire dai numeri positivi 110 -2 111 -1 Pn i *** Se x = i=0 ai 2 , l’operazione di complemento a 2 corrisponde alla seguente ! ! n n n X X X i i i n ai 2 + 1 mod(2n ) 2 − (1 − ai )2 + 1 mod(2 ) = i=0 i=0 i=0 = (2n − x) mod(2n ) Dove mod(y) può essere qui visto come l’operatore riporto della divisione per y e serve a tenere conto che il risultato utile è quello contenuto nella parola a n bit, escludendo quindi i bit che andrebbero in posizioni più a sinistra delle prime n (overflow). *** Dalla tabella, si noti che il complemento a 2 del complemento a 2 di x è ancora x, come nel caso di complemento a 1. Nel caso di 000 si ottiene che il complemento a due è 111 2 + 1 = 10002 . Tenendo solo i 3 bit meno significativi si ottiene ancora la sequenza 000. Anche nel caso di 100 si ottiene lo stesso risultato: 011 2 + 1 = 1002 . Questa volta però la sequenza 100 non può essere interpretata come −0. Si ha infatti che 1002 +1 = 101, che rappresenta −3. Si vede in oltre che 1+(−1) se si utilizza l’algoritmo di somma sulle sequenze 001 e 111 porta a 001 2 + 1112 = 10002 . Prendendo i bit meno significativi otteniamo ancora la sequenza 000. Si noti che ho usato il termine sequenza per indicare le rappresentazioni date nella tabella, mentre le operazioni sono state eseguite su numeri binari puri positivi. Questa distinzione serve a chiarire il fatto che la rappresentazione interpreta i numeri il cui MSB è uguale a 1 come numeri negativi, mentre l’algoritmo usato per le sommare due numeri è sempre quello per i numeri positivi, con l’accortezza di ignorare l’eventuale riporto sul MSB (overflow). Abbiamo quindi eliminato anche il secondo problema delle rappresentazioni viste precedentemente per i numeri negativi: l’algoritmo di somma è lo stesso per qualsiasi coppia di operandi. Questa caratteristica rende il metodo del complemento a 2 il metodo più utilizzato per rappresentare i numeri negativi nei 11 calcolatori digitali. Conoscere le caratteristiche di questa rappresentazione può essere necessaria in certe applicazioni in cui le condizioni sui risultati (ad esempio sapere se è avvenuto un overflow durante una operazione) debbano essere testate direttamente. Abbiamo visto infatti che l’overflow può avvenire anche se le operazioni hanno un esito del tutto legale (questo è dovuto all’operatore mod() che garantisce che il risultato sia contenuto nella parola risultato a prescindere dal valore del riporto nel MSB). In questi casi si deve quindi tenere conto in modo esplicito anche di altre condizioni per sapere se un risultato debba essere considerato valido oppure no. Si ricordi in oltre, che sia per il complemento a 1 che il complemento a 2, i numeri positivi vengono rappresentati come numeri binari puri come mostrato nella sezione 2. Questo vuol dire che se il MSB di un numero è zero, allora il numero rappresentato è il numero binario rappresentato nella sequenza. Vedi esercizi. 5.4 Eccesso-N Un altro modo di rappresentare i numeri negativi, tipicamente utilizzato nel caso in cui sia necessario che il numero di numeri negativi e il numero di positivi siano sostanzialmente diversi, è detto eccesso-N . In questa rappresentazione, il numero binario che rappresenta N sarà associato allo zero, mentre i valori minori di N ai numeri negativi e quelli maggiori a quelli positivi. alla sequenza fatta da tutti zero verrà quindi associato il valore −N . Nella seguente tabella si mostra l’eccesso-5 e l’eccesso-7 nel caso di numeri a 4 bit. Binario Sequenza Eccesso-5 Eccesso-7 0 0000 -5 -7 1 0001 -4 -6 2 0010 -3 -5 3 0011 -2 -4 4 0100 -1 -3 5 0101 0 -2 6 0110 1 -1 7 0111 2 0 8 1000 3 1 9 1001 4 2 10 1010 5 3 11 1011 6 4 12 1100 7 5 13 1101 8 6 14 1110 9 7 15 1111 10 8 Supponiamo di voler calcolare la somma z = x + y, dove i numeri sono rappresentati in eccesso-N. Sia a il numero binario che rappresenta y e b quello che rappresenta z. Ad esempio, se usiamo eccesso-5, x = −3 è rappresentato dal numero a = 2 mentre y = 4 è rappresentato da b = 9. Vediamo quindi che x = a − N e y = b − N . Anche z dovrà essere rappresentato da un numero 12 c, e sarà z = c − N . Quindi deve essere soddisfatta la seguente equazione, equivalente a x + y = z: a − N + b − N = c − N . Questa equazione è soddisfatta da c = a + b − N . Nel nostro esempio 2 + 9 − 5 = 6 che rappresenta 1 = (−3) + 4 in eccesso-5. Vediamo che per trovare la rappresentazione della somma di due numeri si devono sommare le due rappresentazioni e sottrarre il valore dell’eccesso. Se N = 2n−1 − 1, dove n è il numero di bit della parola usata (nella tabella l’esempio è portato per 7 = 24−1 − 1), allora il bit più significativo può ancora essere usato come bit di segno. L’importanza di questa rappresentazione è data dal fatto che è utilizzata per la rappresentazione dei numeri in virgola mobile (impropriamente chiamati “numeri reali”), che vedremo nella prossima sezione. Esercizi: 1. Si dia la rappresentazione in complemento a 1 di -123 con parole di 8 bit. 2. Siano 0110 e 1010 due sequenze di bit che rappresentano i numeri a e b in complemento a 1. Si calcoli la rappresentazione di a+b in complemento a 1 usando solo le rappresentazioni, quindi senza passare per la conversione. 3. Si rappresenti −123 in complemento a 2 con parole di 8 bit. Qual è il valore binario rappresentato interpretato come numero binario puro? 4. Si rappresenti −123 in complemento a 2 con parole di 10 bit. Qual è il valore binario rappresentato interpretato come numero binario puro? 5. Si rappresenti 154 in complemento a 2 con parole di 8 bit. Qual è il valore binario rappresentato interpretato come numero binario puro? 6. Si rappresenti 154 in complemento a 2 con parole di 10 bit. Qual è il valore binario rappresentato interpretato come numero binario puro? 7. Che numero rappresenta la sequenza 11100110 di 8 bit se il sistema di rappresentazione è complemento a 2? 8. Che rappresentazione ha la sequenza di 8 bit in complemento a 2 11100110 se la parola viene allungata a 12 bit? E la sequenza 00010011? 9. Si può rappresentare la sequenza di 12 bit in complemento a 2 111111001011 con 8 bit? E la il numero in complemento a 2 110111001011? 10. Si rappresenti il numero 123 in eccesso-100 con parole di 8 bit. 11. Analogamente a quanto fatto per la somma si trovi la rappresentazione della differenza di due numeri in eccesso-N. 13 6 Rappresentazione binaria dei numeri reali In questa sezione sarà mostrato come i calcolatori digitali memorizzino e elaborino i numeri frazionari in virgola mobile (floating point), impropriamente chiamati numeri reali. Si farà riferimento al sistema di rappresentazione standard denominato ”IEEE Standard 754,” rilasciato nel 1985 e utilizzato in molte di moderni calcolatori. L’idea di base è di memorizzare i numeri in ”notazione scientifica”, con mantissa e esponente: x = ±m · be (3) dove m è un numero frazionario ed è detto mantissa, la base b è naturale e fissato a priori, e infine e è intero ed è chiamato esponente. Lo standard IEEE-754 prevede due tipi di numero in virgola mobile: in singola e in doppia precisione, memorizzati rispettivamente in parole di 32 e 64 bit2 . In figura 1 si vede come i due tipi vengano memorizzati. I numeri indicano il numero di bit utilizzati in ogni sezione della rappresentazione. 1 1 8 23 11 Bitdisegno 52 Esponente Mantissa Figure 1: Suddivisione delle parole per la rappresentazione di numeri IEEE-754 in (a) singola e (b) doppia precisione. I numeri sono il numero di bit utilizzati in ogni sezione. Il termine “mantissa” nel caso di IEEE-754 non è adeguato e si dovrebbe usare “significante”. Il bit di segno vale “0” se il numero rappresentato (x) è positivo e “1” se negativo. L’esponente è memorizzato in eccesso-127 (2 7 − 1) nel caso di singola precisione ed eccesso-1023 (210 − 1) nel caso di doppia precisione. I casi in cui bit dell’esponente siano tutti “0” o tutti “1” sono però dei casi speciali e non sono codificano un esponente numerico. L’esponente minimo è dunque -126 e quello massimo +127. Nello standard IEEE-754, il valore della base b in (3) è 2. I numeri vengono normalizzati in modo che la m nell’equazione (3) sia in ogni caso maggiore o uguale a 1 e minore di 2, ovvero 1≤m=1+ n X mi 2−i < 2. i=1 2 Esiste un numero a 80 bit che viene però usato tipicamente all’interno delle unità di calcolo per migliorare la precisione 14 Nel caso dello standard IEEE-754 l’uno a sinistra del punto decimale non viene memorizzato, e si memorizza solo la parte decimale della mantissa. Nello standard IEEE-754 la parte di parola che codifica la mantissa è detta significante, per evitare confusioni con altre rappresentazioni. Lo zero viene rappresentato con una parola in cui l’esponente e il significante sono nulli (si ricordi che l’esponente non può essere zero se non in casi speciali). Il bit di segno può essere sia a “0” che a “1”. Si hanno quindi due rappresentazioni dello zero. Nel caso di singola precisione il minimo numero maggiore di zero rappresentabile è 1 · 2−126 ≈ 1.2 · 10−38 . Il massimo numero rappresentabile è invece minore di 2 · 2127 ≈ 3.4 · 1038 . Nel caso di precisione doppia questi valori diventano rispettivamente 10−308 e 10308 . Ciò che è importante sapere è che i numeri rappresentabili non sono distribuiti uniformemente sulla retta. Per ogni valore dell’esponente, può essere rappresentato un numero finito di valori pari a 2 23 o 252 , a seconda che si stiano considerando numeri in singola o doppia precisione. Questo darà una maggiore risoluzione per valori vicini a zero e minore per valori più grandi. Se l’esponente ha tutti i suoi bit a 1, allora ci si trova in una delle seguenti situazioni: 1. Il significante è tutto zero: questa configurazione identifica l’infinito (positivo o negativo), si ottiene ad esempio dividendo per zero; 2. Il significante è diverso da zero: Not-a-Number (NaN), che indica un numero non rappresentabile (si ottiene ad esempio dividendo infinito per infinito). *** Numeri visti fin’ora sono detti normalizzati, in quanto la mantissa è sempre maggiore o uguale a 1. Lo standard IEEE-754 prevede anche numeri non normalizzati, in cui il significante può valere meno di 1. Un numero non normalizzato ha l’esponente tutto a zero e il significante diverso da zero. In questo caso il significante diventa una mantissa e rappresenta il numero frazionario in cui il punto decimale sta a sinistra della sequenza di 23 o 52 bit a seconda dei casi. Questa possibilità e‘ stata prevista per consentire una maggiore precisione sui numeri piccoli, consentendo di arrivare a precisioni di 10−45 per il caso a singola precisione e di 10−324 nel caso a doppia precisione. *** 6.1 Somma e prodotto di numeri in virgola mobile Siano x = (1 + mx ) · 2ex e y = (1 + my ) · 2ey , con x ≤ y. In questo caso 0 ≤ mx < 1 e 0 ≤ my < 1 sono i significanti, mentre ex e ey sono gli esponenti nello standard IEEE754. Come si può calcolare x + y? Si deve rinormalizzare il numero più piccolo, eseguire la somma e rinormalizzare il risultato. Esplicitando i termini z =x+y = ((1 + mx )2ex −ey + (1 + my ))2ey = = (1 + mz ) · 2ez 15 Nel caso in cui ex = ey , il calcolo diventa z =x+y = ((1 + mx ) + (1 + my ))2ey = = (2 + mx + my ) · 2ey Sappiamo che mx + my < 2. In questo caso z = (2 −1 (2 + mx + mz ))2 ey +1 = mx + m y 1+ 2 2ey +1 . Come si può notare la normalizzazione avviene modificando l’esponente in modo che la mantissa sia compresa tra 1 e 2. In modo analogo per il prodotto. In questo caso l’esponente risultante è la somma dei prodotti e la mantissa il prodotto delle mantisse. z = (1 + mx + my + mx my )2ex +ey Come risulta immediato, 1 ≤ (1 + mx + my + mx my ) < 4 Se la mantissa è maggiore di 2 è anche qui necessario normalizzare l’esponente al fine di riportarla a essere compresa tra 1 e 2. nei processi di normalizzazione alcuni bit possono essere perduti! La precisione del calcolo può dipendere quindi anche dall’ordine in cui le operazioni in virgola mobile vengono eseguite. Esercizi: 1. Si rappresenti 0.5 come numero a singola precisione. 2. Si rappresenti 1.5 come numero a singola precisione. 7 Rappresentazione binaria delle stringhe Per stringa si intende una sequenza di simboli (in genere presi da un insieme finito detto alfabeto). Si tratta di di associare una opportuna sequenza di bit a ogni simbolo dell’alfabeto. Visto che una sequenza di n bit può rappresentare 2n caratteri, se l’alfabeto contiene m simboli è necessario che 2n ≥ m, ovvero che n ≥ log2 m. In particolare, se siamo intenzionati a minimizzare il numero di bit per simbolo, dobbiamo imporre che n = dlog 2 me, dove dxe è il più piccolo numero intero maggiore o uguale a x (o parte alta di x). Per codificare i caratteri alfanumerici i calcolatori utilizzano generalmente il codice ASCII, che ha 128 simboli (codificabili in 7 bit). La tabella ASCII è facilmente reperibile su WEB. Ci si limita qui a dire che normalmente il codice ASCII usato dipende dalla nazione che prevede che alcuni simboli siano specifici (come le lettere accentate). Il codice ASCII rappresenta anche caratteri speciali come lo spazio, nuora riga, inizio riga, tabulatore, etc. In oltre generalmente si utilizza una versione estesa del codice ASCII che utilizza 256 simboli (1 byte). I 16 simboli da 128 a 255 dipendono dal codice che si sta utilizzando, mentre i primi 128 sono quelli dello standard (con le eventuali modifiche nazionali). L’avvento del WEB e di Internet ha portato all’utilizzo di codici ISO, che sono più versatili e adatti a un ambiente in cui le informazioni vengono scambiate tra le più remote regioni del mondo. Una sequenza di caratteri viene quindi codificata mettendo una dopo l’altra le codifiche dei caratteri. Per evitare ambiguità si utilizza di solito lo stratagemma di assegnare a tutti i simboli codifiche di lunghezza fissa (ad esempio un byte), ma altre volte si preferiscono schemi più complessi in cui si impone che la codifica di un carattere non possa essere il prefisso di un’altra. Questi codici riescono tipicamente a ridurre la quantità di spazio necessario a immagazzinare le sequenze. 17