Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

5
voti

LogicBignami (XI)

Indice

I sistemi di numerazione (parte terza)

In questa terza parte vedremo come eseguire le principali operazioni matematiche con i sistemi di numerazioni diversi da quello decimale e vedremo come rappresentare i numeri negativi.

Nei diversi sistemi numerici si applicano le medesime regole della matematica che già conosciamo per il sistema numerico decimale e, nello specifico, non volendo uscire dal target di questi articoli, per quelli di nostro interesse (esadecimale, ottale e binario), illustreremo solamente come eseguire le 4 \; operazioni di base: somma, sottrazione, moltiplicazione e divisione.

In particolare approfondiremo maggiormente le operazioni matematiche eseguite con i numeri binari essendo questi manipolabili direttamente tramite circuiti elettronici basati sulla logica booleana a due elementi.

I numeri negativi nei sistemi numerici ottale ed esadecimale

Sulla rappresentazione dei numeri negativi nei due sistemi numerici ottale e esadecimale non c'è molto da dire in quanto vengono rappresentati, e trattati nelle diverse operazioni matematiche (es. la regola dei segni di prodotto e divisione), come gli analoghi numeri negativi del sistema numerico decimale: per individuare un numero N < 0 \; basta apporre il segno "-" davanti al MSD del numero stesso.

Così, ad esempio, − 55(10) = − 67(8) = − 37(16)

Operazioni matematiche di base nei sistemi numerici ottale e esadecimale

La principale differenza nell'esecuzione delle 4 \; operazioni fondamentali nei sistemi numerici ottale e esadecimale, rispetto al sistema numerico decimale, è dovuta al diverso numero di caratteri utilizzati per rappresentare le singole cifre che, ovviamente, porta ad avere diverse regole per riporti (somme/prodotti) e prestiti (sottrazioni/divisioni).

Così, ad esempio, nel sistema numerico ottale, quando sommiamo una unità al numero 7 \; (ultimo carattere disponibile per rappresentare gli 8 \; numeri di una cifra ottale), non otterremo il numero 8 \; come nel sistema numerico decimale, bensì il numero 0 \; con il riporto di una unità alla cifra di peso immediatamente superiore.

Analogamente, nel sistema numerico esadecimale, se sommiamo una unità al numero 9 \;, non otterremo il numero 0 \; con il riporto di una unità alla cifra di peso immediatamente superiore come nel sistema numerico decimale, bensì il numero A \;, decimo carattere disponibile per rappresentare i 16 \; numeri di una cifra esadecimale.

In base a ciò si possono costruire le seguenti due tabelle (quella superiore per il sistema numerico ottale e quella inferiore per quello esadecimale) dove vengono rappresentate la somma di due cifre con l'eventuale riporto indicato in rosso:

Queste tabelle ci tornano utili nell'esucuzione delle operazioni di somma.

Ad esempio se volessimo eseguire la somma 3721_{(8)} + 415_{(8)} \;, in base alla tabella sopra riportata, otterremo:

Similmente se volessimo eseguire la somma A092_{(16)} + FF6_{(16)} \; avremo:

Per quanto riguarda il riporto nell'operazione di sottrazione si applicano, invece, le seguenti regole a seconda del sistema numerico utilizzato:

sistema numerico ottale
Nel sistema numerico ottale, se una cifra o_{n_s} \; del sottraendo è minore della cifra pari peso o_{n_m} \; del minuendo, quest'ultima dovrà andare in prestito di una unità dalla cifra minuendo di peso immediatamente superiore o_{(n+1)_m} \;: questo prestito equivale a sommare 8 \; unità alla cifra o_{n_m} \;.

Quindi se eseguiamo la sottrazione 465_{(8)} - 73_{(8)} \; dobbiamo procedere nel seguente modo:

sistema numerico esadecimale
Nel sistema numerico esadecimale, se una cifra h_{n_s} \; del sottraendo è minore della cifra pari peso h_{n_m} \; del minuendo, quest'ultima dovrà andare in prestito di una unità dalla cifra minuendo di peso immediatamente superiore h_{(n+1)_m} \;: questo prestito equivale a sommare 16 \; unità alla cifra h_{n_m} \;.

Per cui se eseguiamo, ad esempio, la sottrazione D037_{(16)} - F2_{(16)} \; dobbiamo procedere nel seguente modo:

Visto che le operazioni con il sistema numerico esadecimale, che contiene anche delle lettere, potrebbe risultare ostico all'inizio, diamo una breve spiegazione al procedimento seguito per l'esecuizione della succitata operazione, ricodando la corrispondenza di valori esadecimale / decimale A = 10, \; B = 11, \; C = 12, \; D = 13, \; E = 14, \; F = 15. \;

Partendo dal LSD di minuendo e sottraendo abbiamo:

- 7_{(16)} - 2_{(16)} = 5_{(16)} \;

- Abbiamo che il numero 3_{(16)} \; del minuendo risulta minore del valore della corrisponde cifra, di pari peso, del sottraendo F_{(16)} \;, quindi dobbiamo andare in prestito dalla cifra di peso immediatamente superiore del minuendo.

- Ma tale cifra è pari a 0 \; quindi, al momento, non ci può fornire alcun prestito, per cui scaliamo in avanti di un'altra unità nel peso delle cifre e andiamo in prestito dalla cifra D \;.

- Quindi abbiamo:

Per quanto riguarda le operazioni di moltiplicazione e divisione, per semplicità (*), soprattutto quando si parla di divisioni a due o più cifre, è preferibile eseguire la trasformazione dei numeri in ottale (o esadecimale) nei corrispondenti decimali, eseguire in tale sistema numerico le operazioni richieste, quindi trasformare il risultato nuovamente in ottale (o esadecimale).

(*) Ci si riferisce all'esecuzioni delle suddette operazioni senza l'ausilio di dispositivi di calcolo elettronici.

Rimane comunque possibile eseguire l'operazione di moltiplicazione favendo riferimento alle seguenti tavole pitagoriche relativi ai sistemi numerici ottale e esadecimale:

Tavola_pitagorica_ottale

Tavola_pitagorica_ottale

Tavola_pitagorica_esadecimale

Tavola_pitagorica_esadecimale

Note:

- In entrambe le tabelle il numero 10 \; indicato nelle righe e nelle colonne ha valore coerente con il sistema numerico a cui si riferisce la tabella stessa, per cui:

Tavola pitagorica ottale: 10(8) = 8(10)
Tavola pitagorica esadecimale: 10(16) = 16(10)

- In entrambe le tavole manca la riga e la colonna con il numero 0 \; in quanto vale sempre la regola matematica 0 \cdot n = 0 \;, qualunque sia il numero n.

Vediamo adesso un paio di esempi di moltiplicazione tenendo presente che il procedimento è identico a quello che già conosciamo per il sistema numerico decimale e che, per le somme dei riporti ci serviranno, ovviamente, le relative tabelle viste all'inizio del paragrafo:

sistema numerico ottale
Eseguiamo la moltiplicazione 14_{(8)} \cdot 25_{(8)} \;

(in rosso è indicato il riporto relativo alla moltiplicazione per 5 \; mentre in blu quello relativo alla moltiplicazione per 2 \;)

sistema numerico esadecimale
In questo esempio eseguiamo, invece, la moltiplicazione FC_{(16)} \cdot 5D_{(16)} \;

(in rosso è indicato il riporto relativo alla moltiplicazione per D \; mentre in blu quello relativo alla moltiplicazione per 5 \;, in verde, invece, sono riportati i riporti relativi alla somma dei due prodotti distinti.)

Per quanto riguarda, invece, l'operazione di divisione, se non ci si vuole affidare alla doppia conversione, ossia non si vuole passare dal sistema numerico ottale (o esadecimale) al sistema numerico decimale, eseguire l'operazione, e, a risultato ottenuto, eseguire il passaggio di conversione inverso, il sistema migliore, seppur ripetitivo, per eseguire direttamente l'operazione è quello della divisione per sottrazioni successive.

Nota: seppure con nome simile, questo metodo non ha nulla a che vedere con quello analizzato in LogicBignami X per la trasformazione di un numero decimale nel corrispondente numero binario.

In pratica dati due numeri, il dividendo A_{(n)} \; e il divisore B(n), con B_{(n)} \ne 0 \;, il quoziente Q_{(n)} = \frac {A_{(n)}}{B_{(n)}} \; si può ottenre con la seguente procedura:

considerando \left | A_{(n)} \right | > \left | B_{(n)} \right | \;

1) Eseguiamo una prima sottrazione \left | A_{(n)} \right | - \left | B_{(n)} \right | \;, dalla quale ricaviamo il numero D_{(n)_1}

2) Ripetiamo l'operazione di sottrazione, questa volta tra D_{(n)_1} \; e \left | B_{(n)} \right | \;, ricavando un nuovo numero D_{(n)_2}

3) Ripetiamo il passo 2), utilizzando ogni volta che esguiamo l'operazione di sottrazione, il numero D_{(n)_{(m-1)}} \; ricavato dall'operazione precedente, fino a quando otterremo un numero D_{(n)_{(...)}} < \left | B_{(n)} \right | \;, oppure fino a quando il risultato dell'ultima operazione di sottrazione eseguita è uguale a 0 \;

A questo punto sommiamo il numero di volte che abbiamo eseguito l'operazione di sottrazione: questo rappresenterà il valore del quoziente Q_{(n)} \; , mentre il numero D_{(n)_{(...)}} < \left | B_{(n)} \right | \;, se presente, rappresenterà il resto R_{(n)} \; dell'operazione di divisione.

considerando, invece, \left | A_{(n)} \right | < \left | B_{(n)} \right | \;

Prima di procedere con il punto 1) precedente, dobbiamo moltiplicare il numero A_{(n)} \; per la minima potenza di dieci 10^m \; (cioè con il minimo esposnente possibile) tale da rendere valida l'espressione \left | A_{(n)} \right |\cdot 10^m > \left | B_{(n)} \right | \;

Ciò equivale ad aggiungere m \; cifre a 0 davanti al valore del quoziente Q \;.

Esempio, se dovessimo eseguire la divisione 1_{(16)} \; : \; FA_{(16)} \; dovremmo moltiplicare 1_{(16)} \; per 10_{(16)}^2, ottenendo 100_{(16)} > FA_{(16)} \; che ci permetterebbe, così, di iniziare con la sequenza di sottrazioni successive: questo ci porterà ad avere, nel risultato finale, un quoziente preceduto da due cifre 0, cioè che il numero inizierà dalla seconda cifra frazionaria: 0,0...

In pratica il procedimento della divisione per sottrazioni successive può essere riassunto dai due schemi di seguito riportati:

Da notare che il medesimo discorso si attua quando, raggiunto un valore di divisione con resto si voglia continuare a dividere: in questo caso si moltiplica per 10 il resto e si continua con le sottrazioni: da questo momento la somma delle sottrazioni eseguite corrisponderà alla prima cifra frazionaria del quoziente.

Se si raggiunge un nuovo resto e si vuole proseguire, si ripete la procedura appena illustrata, aggiungendo sempre una cifra frazionaria al quoziente, fino a raggiungere il numero di cifre frazionarie volute o un resto pari a 0 \;.

Vediamo, allora, un esempio pratico dell'applicazione di questo metodo, eseguendo la divisione 50F_{(16)} \; : \; FC_{(16)}.

Applicando la procedura precedentemente descritta si ottiene la seguente serie di sottrazioni:

prima sottrazione: 50F_{(16)} - FC_{(16)} = 413_{(16)} \;
seconda sottrazione: 413_{(16)} - FC_{(16)} = 317_{(16)} \;
terza sottrazione: 317_{(16)} - FC_{(16)} = 21B_{(16)} \;
quarta sottrazione: 21B_{(16)} - FC_{(16)} = 11F_{(16)} \;
quinta sottrazione: 11F_{(16)} - FC_{(16)} = 23_{(16)} \;

a questo punto abbiamo 23_{(16)} < FC_{(16)} \;, quindi il nostro quoziente intero sarebbe la somma delle sottrazioni eseguite, cioè pari a 5 \;.

Per tanto, se considerassimo una divisione con quoziente e resto, il nostro risultato sarebbe

50F_{(16)} \; : \; FC_{(16)} = 5_{(16)} \; resto \; 23_{(16)} \;.

Decidiamo, però di continuare, al fine di ottenere un numero esadecimale frazionario come risultato, quindi moltiplichiamo per 10(16) il numero 23_{(16)} \; e continuiamo con la serie di sottrazioni:

prima sottrazione: 230_{(16)} - FC_{(16)} = 134_{(16)} \;
seconda sottrazione: 134_{(16)} - FC_{(16)} = 38_{(16)} \;

abbiamo, nuovamente raggiunto una cifra minore di FC_{(16)} \;, quindi la nostra prima cifra frazionaria, quella di peso 16^{-1} \;, equivarrà a 2 \;, avendo eseguito tale numero di sottrazioni.

ma volendo un'ulteriore cifra frazionaria per il risultato, moltiplichiamo nuovamente per 10_{(16)} \; questa volta il numero 38_{(16)} \; e proseguiamo

prima sottrazione: 380_{(16)} - FC_{(16)} = 284_{(16)} \;
seconda sottrazione: 284_{(16)} - FC_{(16)} = 188_{(16)} \;
terza sottrazione: 188_{(16)} - FC_{(16)} = 8C_{(16)} \;

A questo punto ci fermiamo (8C_{(16)} < FC_{(16)}) \;, l'ulteriore cifra frazionaria, quella di peso 16^{-2} \;, sarà pari a 3 \; e visto che non abbiamo un resto uguale a 0 \;, il risultato finale della nostra operazione di divisione sarà:

50F_{(16)} \; : \; FC_{(16)} \cong 5,23_{(16)} \;.

Analogamente si procede con il sistema numerico ottale.

Con questo esempio concludiamo l'analissi delle pricnipali operazioni matematiche con i sistemi numerico ottale e esadecimale, nel prossimo paragrafo analizzeremo le stesso nel sistema numerico binario.

Somma e sottrazione nel sistema numerico binario

Prima di continuare dobbiamo introdurre le regole per l'esecuzione della somma e della sottrazione nel sistema numerico binario in quanto ci serviranno negli esempi che seguiranno.

Al momento saranno illustrate facendo riferimento ai soli numeri binari naturali, mentre in seguito prenderemo in considerazione anche i numeri binari con segno.

Le operazioni di somma e sottrazione, nel sistema numerico binario, rispondono alla seguente tabella, dove b_{A_n} \; e b_{B_n}\; rappresentano l'ennesimo bit dei numeri binari A_{(2)} \; e B_{(2)} \;.

b_{A_n}
b_{B_n}
b_{A_n} + b_{B_n}
b_{A_n} - b_{B_n}
0
0
0
0
0
1
1
1
1+1 (**) in prestito
1
0
1
1
1
1
0
+ 1 (*) in riporto
0

(*) 1_{(2)} + 1_{(2)} = 0 \; con riporto di un bit settato a 1 \; da sommare nella posizione relativa al bit di peso immediatamente superiore.

(**) 0_{(2)} - 1_{(2)} = 1 \; con prestito di un bit a 1 \; da sottrarre dal primo bit di peso superiore che risulterà settato a 1 \;: questo equivale a trasformare la sottrazione del bit che ha ricevuto il prestito in (1_{(2)} + 1_{(2)}) - 1_{(2)} = 1_{(2)} \;.

I numeri negativi nel sistema numerico binario

Nei sistemi numerici ottale e esadecimale abbiamo visto che i numeri negativi seguono la stessa rappresentazione e le stesse regole dei numeri nel sistema numerico decimale.

Nessuno ci vieterebbe di usare un metodo simile anche per il sistema numerico binario, scrivendo, ad esempio +11_{(2)} = +3_{(10)} \; e -11_{(2)} = -3_{(10)} \;.

Questo non sarebbe un problema se le operazioni eseguite su questi numeri fossero fatte solo a livello umano, ma a noi interessa poter manipolare questi numeri tramite circuiti basati sull'algebra booleana a due valori, per cui dobbiamo associare i segni "+" e "-" ai simboli 1 \; e 0 \;.

Per mantenere validi i costrutti che una condizione logica vero corrisponde ad uno stato logico 1 \; e una condizione logica falso corrisponde ad uno stato logico 0 \; (vedi LogicBignami II), considerando che, il segno "+", negli altri sistemi numerici è, solitamente, sottinteso, mentre si evidenzia solo il segno "-" per indicare che un numero è negativo, storicamente si è scelto di indicare con lo stato logico 1 \; il segno "-" ( esprimendo il concetto: è negativo - vero) e con 0 \; il segno "+" (esprimendo il concetto: non è negativo - falso).

Il modo di rappresentare i numeri binari con segno (signed), ha subito un'evoluzione nel tempo: di seguito, analizzeremo il metodo a modulo e segno (o signed magnitude), il metodo a complemento a 1, il metodo a complemento a 2 e il metodo offset binary o eccesso N (o excess N).

Modulo e segno

Questo è stato il primo ad essere implementato ed è il metodo più semplice e immediato per rappresentare un numero binario con segno in quanto si basa sul medesimo concetto di rappresentazione noto negli altri sistemi numerici.

In pratica, dato un numero binario naturale di n \; bit, il MSB cessa di avere questo ruolo per diventare bit di segno, e il ruolo di MSB viene assunto dal bit n - 1 \;.

Quindi il bit n \; sarà settato a 1 \; se il numero binario è negativo, altrimenti a 0 \; se è positivo, mentre gli n − 1 bit restanti rappresenteranno il valore assoluto (modulo) del numero binario:

ATTENZIONE
Annotazione valida qualunque sia il metodo utilizzato per rappresentare un numero binario con segno.

Essendo un numero binario con bit di segno (o singed) in tutto e per tutto visivamente identico ad un numero binario senza segno (o unsigned), si dovrà sempre esplicitare se si sta trattando di uno o dell'altro, in quanto il valore ad esso associato potrà risultare, nei due casi, differente.

Considerando il metodo modulo e segno, ad esempio, i numeri binari 011 \; e 101 \; possono rappresentare i seguenti valori:

Caratteristiche principali:

1) Doppia rappresentazione dello zero
Per come è strutturato il numero binario in modulo e segno, avremo la rappresentazione sia del valore +0 \; che del valore -0 \;:
ad esempio, dato un numero binario in modulo e segno di 4 \; bit avremo le due combinazioni
0000_{(2)} = +0 \;
1000_{(2)} = -0 \;
2) Valori massimi rappresentabili (vedi LogicBignami IX)
dato n \; il numero di bit che compongono il numero binario in modulo e segno, il valore massimo associato sarà pari a \pm (2^{n - 1}-1) \; ossia:
da +0 \; a +(2^{n - 1}-1)_{(10)} \;
da -0 \; a -(2^{n - 1}-1)_{(10)} \;.

Esempio di rappresentazione dei valori associati ad un numero binario in modulo e segno di 4 \; bit

L'utilizzo dei numeri binari in modulo e segno determina alcuni problemi:
- Abbiamo uno spreco di risorse dovuta alla doppia rappresentazione del valore 0 \;

- Nelle operazioni matematiche si devono trattare separatamente il bit di segno e il modulo e cioè comporta, ovviamente, delle complicazioni circuitali.

In merito a quest'ultimo punto, e tralasciando il concetto di overflow (traboccamento) che affronteremo nei prossimi paragrafi, e quindi rimanendo sempre entro i limiti massimi rappresentabili da un determinato numero binario in modulo e segno, vedremo che solo la somma algebrica di due numeri binari positivi può essere svolta bit per bit, negli altri casi si deve analizzare separatamente il bit di segno e moduloper decidere se eseguire una somma o una sottrazione.

Ecco alcuni esempi di somma bit per bit di due numeri binari in modulo e segno:

A_{(2)} > 0, \; B_{(2)} > 0 \;

Esempio: 0101_{(2)} = 5_{(10)} \; e 0001_{(2)} = 1_{(10)} \;.

Quindi, come anticipato, nel caso di somma di due numeri binari positivi, l'esecuzione dell'operazione bit per bit non crea problemi, il risultato è corretto.

A_{(2)} \; e B_{(2)} \; discordi o entrambi negativi

Esempio: 0101_{(2)} = 5_{(10)} \; e 1010_{(2)} = -2_{(10)} \;.

In questo frangente non è possibile eseguire la somma bit per bit, perchè la rappresentazione in modulo e segno per rappresentare i numeri binari negativi non permette di eseguirla direttamente come somma algebrica (vedremo più avanti un altro tipo di codifica che, invece lo permette), infatti otterremo

Come si vede il risultato è completamente sbagliato in quanto al posto dell'atteso 0011_{(2)} = 3_{(10)} \; abbiamo avuto un 1111_{(2)} = -7_{(10)} \;

Da notare che lo stesso problema di inconcruenza del risultato si otterrebbe se entrambi i numeri binari fossero negativi in quanto la somma dei due bit di segno (entrambi settati a 1 \;) porterebbe ad un risultato pari a 0 \; (con riporto), e quindi ad avere un numero binario positivo.

Ecco perchè, con il metodo di rappresentazione a modulo e segno è necessario separare il modulo dal segno prima di procedere all'operazione.

In pratica l'esecuzione di operazioni mediante circuiti elettornici, con numeri binari di segno opposto o entrambi negativi, si deve prevedere, oltre al normale circuito adibito alla somma:

- un circuito che analizzi i segni dei due numeri, per trasformare una somma in una sottrazione e per determinare il segno del risultato.

- un circuito di comparazione per ottenere, se necessario, sempre una sottrazione di valore positivo a cui aggiungere successivamente il segno opportuno.

- un circuito per eseguire la sottrazione quando necessario.

Nonostante queste complicazioni, a cavallo del 1950 - 1960, esistevano macchine che eseguivano operazioni con numeri binari rappresentati in modulo e segno (Es. IBM 704, 709 e 709X).


Complemento a 1

Questo sistema di implementazione dei numeri binari con segno deriva direttamente dal precedente e consiste nella rappresentazione dei numeri binari negativi mediante l'applicazione della funzione logica booleana di negazione (vedi LogicBignami II) applicata, bit per bit ai corrispondenti numeri binari positivi rappresentati in modulo e segno.

Per questo, sempre considerando dei numeri binari con segno a 4 \; bit, otterremo la seguente tabella dove, ovviamente, la rappresentazione dei numeri binari positivi non varia:

Le caratteristiche principali sono, praticamente identiche al precedente sistema di rappresentazione:

1) Doppia rappresentazione dello zero
Essendo derivato dal sistema in modulo e segno anche qui avremo la rappresentazione sia del valore +0 \; che del valore -0 \;, solo che la rappresentazione del valore -0 \; equivarrà alla negazione, bit per bit di quella relativa al valore +0 \;:
ad esempio, dato un numero binario con segno di 4 \; bit avremo le due combinazioni
0000_{(2)} = +0 \;
1111_{(2)} = -0 \;
2) Valori massimi rappresentabili
sono esattamente identici a quelli ottenibili con il metodo in modulo e segno, per cui:
dato n \; il numero di bit che compongono il numero binario rappresentato in modulo e segno, il valore massimo associato sarà pari a \pm (2^{n - 1}-1) \; ossia:
da +0 \; a +(2^{n - 1}-1)_{(10)} \;
da -0 \; a -(2^{n - 1}-1)_{(10)} \;.

La rappresentazione dei numeri binari in complemento a 1 permette, però, di eseguire le somme algebriche senza dover ricorrere a circuiti di separazione e controllo del bit di segno e conseguente selezione tra operazione di addizione o sottrazione, semplicemente fornisce il risultato corretto dalla somma bit per bit dell'intero numero binario, bit di segno compreso.

Questo grazie alla tecnica di end-around carry che, in pratica, esegue un'ulteriore somma nel caso dovesse verificarsi un riporto dal bit di segno.

Vediamo allora, alcuni esempi, escludendo la somma di numeri binari positivi in quanto è identica a quella che si ottiene nel metodo di rappresentazione in modulo e segno.

Nota: in magenta evideziamo la posizione del bit di segno.

A_{(2)} \; e B_{(2)} \; di segno opposto.

Eseguiamo la somma tra i numeri binari con segno 0111_{(2)} = 7_{(10)} \; e 1010_{(2)} = -5_{(10)} \;

Come si può notare abbiamo un primo risultato pari a 0001_{(2)} \; che risulterebbe errato, però con un riporto sul bit di segno, evidenziato in blu.

Applichiamo quindi la tecnica dell' end-around carry e sommiamo questo riporto al risultato ottenendo 0010_{(2)} = 2_{(10)} \; che è, appunto, quello che ci attendevamo.

Se, invece, sommaimo 1000_{(2)} = -7_{(10)} \; e 0110_{(2)} = 6_{(10)} \; otteniamo

In questo caso il risultato è immediatamente esatto, 1110(2) = − 1(10) ed, infatti non è presente nessun riporto dal bit di segno.

A_{(2)} \; e B_{(2)} \; entrambi negativi.

In questo caso la tecnica dell' end-around carry è sempre da applicare in quanto entrambi i bit di segno sono sempre settati a 1 \; e quindi generano sempre un riporto.

Sommiamo i numeri 1011_{(2)} = -4_{(10)} \; e 1100_{(2)} = -3_{(10)} \; ottenendo

Come preannunciato si può notare che, per ottenere il risultato corretto 1000_{(2)} = -7_{(10)} \;, si deve applicare la tecnica dell' end-around - carry.

Quindi, rispetto alla rappresentazione in modulo e segno, adesso si possono eseguire somme algebriche semplicemente controllando solo la presenza di un eventuale riporto generato dalla somma del bit di segno e, nel caso, attivando la procedura dell' end-around carry.

Il poter eseguire la somma algebrica permette di evitare di implementare un circuito adibito all'operazione di sottrazione: per eseguire tale operazione è sufficiente passare ad un circuito sommatore il minuendo e il complemento a 1 del sottraendo.

Rimane comunque ancora insoluta la questione della doppia rappresentazione del valore 0 \;.

Complemento a 2

Per risolvere anche il problema della doppia rappresentazione del valore 0 \; si ricorre al metodo del complemento a 2 per la rappresentazione dei numeri bianri negativi.

Nel sistema numerico decimale, conosciamo il complemento a 10 che equivale alla differenza:

10^n - A_{(10)} \;

con n\; tale da avere la potenza di 10 \; immediatamente più grande del numero A_{(10)} \; (in pratica n \; corrisponde al numero di cifre di A_{(10)}\;):

Esempio il complemento a 10 del numero decimale 45_{(10)} \; è 10^2 - 45_{(10)} = 55_{(10)} \;

Analogamente si ha la definizione di complemento a 2, che equivale alla differenza:

[2^n]_{(2)} - B_{(2)} \;

Nota

Con il termine [2^n]_{(2)} \; indichiamo il numero binario corrispondente al valore 2n:
dall'articolo LogicBignami IX sappiamo che corrisponde ad un bit settato a 1 \; seguito da n \; bit settati a 0 \;
(in prarica un numero binario lungo n + 1 bit).

Esempio: 26 = 1000000(2)

dove n \; ha un valore pari al numero di bit (segno compreso) che compongono il numero B_{(2)} \;:

Esempio il complemento a 2 di un numero binario composto da 3 \; bit, tipo 011_{(2)} \;, coorisponderà a 1000(2) − 011(2) = 101(2).

Il complemento a 2 di un numero binario si può ricavare anche tramite due sistemi alternativi all'operazione di sottrazione di definizione appena vista.

Complemento a 2 da complemento a 1

Dalla tabella relativa al paragrafo sul complemento a 1 si vede che la somma di un numero binario A_{(2)} \; con il suo complemento a 1 A_{(2)_{C1}} \;, equivale ad un numero binario, con un numero di bit pari a A_{(2)} \;, ma tutti settati a 1\;: tale numero binario sappiamo coincidere con il valore 2^n - 1 \;.

Quindi possiamo scrivere:

A_{(2)} + A_{(2)_{C1}} = 2^n - 1 \;

Mentre, dalla definizione di complemento a 2 appena data, e considerando sempre il medesimo numero binario A_{(2)} \; possiamo scrivere che:

A_{(2)} + A_{(2)_{C2}} = 2^n \;

dove il termine A_{(2)_{C2}} \; rappresenta il complemento a 2 di A_{(2)} \;.

Se uguagliamo le due espressioni rispetto al numero binario A_{(2)} \; otteniamo:

2^n - 1 - A_{(2)_{C1}} =  2^n - A_{(2)_{C2}} \;

ossia

A_{(2)_{C2}} = A_{(2)_{C1}} + 1
Quindi

Il complemento a 2 di un numero binario equivale al complemento a 1 del medesimo numero a cui va poi sommata una unità.

Regola della negazione dopo il primo bit a 1

Questa è una regola pratica che permette di ottenere il complemento a 2 di un numero binario senza eseguire nessuna operazione:

Dato un numero binario, il suo complemento a 2 corrisponde al numero scritto con le medesime cifre, partendo dal LSB, fino alla prima cifra a 1 \; compresa, dopo di che si comlementa a 1 i restanti bit.

Vediamo allora l'applicazione del complementoa a 2 ai numeri binari positivi di 5 \; bit, bit di segno compreso, per ricavare i corrispondenti numeri binari negativi:

Notiamo alcune particolarità di questo sistema di rappresentazione dei numeri binari negativi:

1) Unico valore associato a 0 \; pari a 00000_{(2)} \;: ciò è dovuto all'operazione di sottrazione per trovare il complemento a 2 del valore 0 \;, perchè 100000_{(2)} - 00000_{(2)} = 100000_{(2)} \; è in overflow (vedremo nel prossimo paragrafo cosa significa) per cui il risultato "utilizzabile" è 00000_{(2)} \;.
2) In conseguenza a quanto esposto al punto 1), rimane disponibile la combinazione di bit corrispondenti al numero binario negativo 10000_{(2)} \; a cui non corrisponde nessun numero binario positivo (il complemento a 2 di tale numero è il numero stesso), ad esso viene associato il valore − 24 che, di fatto, non esite come valore positivo rappresentabile con lo stesso numero di bit.
Quindi, con il metodo del complemento a 2, il massimo valore rappresentabile con un numero binario di n \; bit si estenderà
dal valore positivo (2^{n-1} - 1)_{(10)} \; al valore negativo -(2^n)_{(10)} \;.

La rappresentazione dei numeri binari negativi con il sistema del complemento a 2 permette anche di eseguire le operazioni di somma algebrica senza dover ricorrere alla tecnica del' end-around carry necessario, in alcuni frangenti, con il sistema di rappresentazione in complemento a 1 visti in precedenza.

Vediamo allora, come eseguire gli stessi esempi di operazioni, escludendo, anche questa volta, la somma di numeri binari positivi in quanto è identica a quella che si ottiene nel metodo di rappresentazione in modulo e segno.

Nota: in magenta evideziamo la posizione del bit di segno.

A_{(2)} \; e B_{(2)} \; di segno opposto.

Eseguiamo la somma tra i numeri binari con segno 0111_{(2)} = 7_{(10)} \; e 1011_{(2)} = -5_{(10)} \;

Come si vede il risultato è corretto: 0010(2) = 2(10) senza aver avuto bisogno di riccorrere alla tecnica dell' end-around carry.

Se, invece, sommaimo 1001_{(2)} = -7_{(10)} \; e 0110_{(2)} = 6_{(10)} \; otteniamo

Il risultato ottenuto 1111_{(2)} \;, essendo un numero binario negativo è espresso, ovviamente, in complemento a 2 ed equivale al valore − 1(10).

Visto che visualizzare il valore assoluto assunto da un numero bianrio negativo, espresso in complemento a 2 può risultare meno immediato del corrispondente espresso in complemento a 1, per trovarlo basta eseguire nuovamente l'operazione di complemento a 2 sul numero binario negativo, in questo modo si ottiene il corrispondente positivo (ad esclusione del numero binario di valore − 2n di cui, come abbiamo detto, non esiste corrispondente positivo, ma il cui valore è, comunque, immediato).

A_{(2)} \; e B_{(2)} \; entrambi negativi.

Sommiamo i numeri 1100_{(2)} = -4_{(10)} \; e 1101_{(2)} = -3_{(10)} \; ottenendo

Escludendo il riporto sul bit di segno, in quanto i nostri numeri binari sono di soli 4 \; bit, il risultato 1001(2) = − 7(10) è corretto.

Il metodo del complemento a 2 è, di fatto, quello più utilizzato per la rappresentazione dei numeri binari negativi perchè permette di eseguire l'operazione di somma algebrica senza ulteriori controlli del risultato se non quello dell'eventuale overflow, che analizzeremo in seguito, e che, comunque, è necessario anche negli altri metodi già analizzati.

Eccesso - N

Questo sistema non è una evoluzione dei quelli precedenti in quanto rappresenta esclusivamente un modo diverso di rappresentare il valore attribuito ad un numero binario naturale trasformandolo in un numero binario con segno.

La codifica del valore si basa sulla seguente formula:

dato

un numero binario naturale di n \; bit

il suo valore in eccesso - N equivale a

N_{10_{ex-N}} = \sum_{i=0}^{n-1}{b_i\;2^i} - 2^{n-1} \;

Il termine 2^{n-1} \; determina il nome della codifica, così, se ad esempio abbiamo un numero a 5 \; bit, otteniamo (2^4)_{(10)} = 16_{(10)} \; da cui la decodifica eccesso - 16.

Di seguito la codifica eccesso - 8 dei numeri binari naturali a 4 \; bit:

Come si vede hanno una decodifica dei numeri binari con segno opposta, rispetto a quanto visto fino ad ora: il bit di segno settato a 0 \; indica un numero binario negativo, viceversa uno positivo.

Così com'è strutturato il numero binario rappresentato in Eccesso - N non può essere usato per eseguire direttamente una somma bit per bit, compreso il bit di segno: infatti è evidente che la somma di due numeri negativi (o due numeri positivi), può portare ad un errore nel bit di segno.

Ad esempio se sommiamo 0111_{(2)} = -1_{(10)} \; e 0010_{(2)} = -6_{(10)} \; otteniamo 1001_{(2)} = 1_{(10)} \; errato sia per segno che per valore: da notare che se il segno fosse stato corretto, il numero rappresentato sarebbe stato quello giusto 0001(2) = − 7(10)

In pratica andrebbe trattato come i numeri binari rappresentati in modulo e segno, separando la gestione del bit di segno dalla somma vera e propria del valore numerico.

Oppure, notando che invertendo semplicemente il bit di segno nella suddetta tabella, i numeri binari negativi vengono rappresentati come quelli in complemento a 2 e quelli positivi come quelli in modulo e segno (come negli altri sistemi visti in precedenza), potremmo eseguire le operazioni di somma algebrica come visto per i numeri binari rappresentati in complemento a 2.

Di seguito raccogliamo in un'unica tabella i valori che possono assumere i numeri binari a 4 \; bit a seconda del sistema di rappresentazione usato, tra quelli più comunemente utilizzati per eseguire operazioni aritmetiche:

In prossimi articoli vedremo anche altri sistemi di rappresentazione, per lo più utilizzati per la codifica delle informazioni nei sistemi di trasmissione dati.

Concludo questo articolo per non farlo esageratamente prolisso, nel prossimo analizzeremo la questione dell' overflow, le operazioni di moltiplicazione e divisione, sempre nel sistema numerico binario e la rappresentazione dei numeri binari frazionari in virgola mobile.

LogicBignami - Indice articoli correlati

8

Commenti e note

Inserisci un commento

di ,

Mi fa piacere che ti possano essere utili.
Buon lettura allora!!

Rispondi

di ,

Grazie Max, si ho notato. Ma per assimilare bene i concetti devo poter leggere e magari anche rileggere senza che qualche rompiscatole di turno m'interrompa. Leggerò tutto. Un cordiale saluto.

Rispondi

di ,

Grazie mille, Ivo...
Per gli articoli precedenti clicca sul link relativo all'indice, che fai sicuramente prima.
Sto cercando di finire anche il successivo, ma purtroppo vado un po' a rilento... Groan!

Rispondi

di ,

Che lavoro, complimenti. Devo cercare anche i precedenti.

Rispondi

di ,

Grazie mille, Clavicordo.

Rispondi

di ,

Molto ben spiegato, complimenti!

Rispondi

di ,

Mi scuso per il ritardo nella pubblicazione ma l'ho dovuto rielaborare più e più volte per farne un riassunto degno di questo nome...
... mi veniva sempre o troppo prolisso o troppo stringato.

Rispondi

Inserisci un commento

Per inserire commenti è necessario iscriversi ad ElectroYou. Se sei già iscritto, effettua il login.