Salta al contenuto
Note per Studenti Numeri con segno, complemento a 2, sottrazione e overflow

Numeri con segno, complemento a 2, sottrazione e overflow

In questa pagina 7

Il sommatore (Sommatori binari - half adder, full adder e ripple carryHalf adder (2 ingressi): $S=X\oplus Y$, $C=XY$. Full adder (3 ingressi, con riporto in ingresso $Z$): $S=X\oplus Y\oplus Z$, $C=XY+XZ+YZ=G+PZ$ con $P=X\oplus Y$, $G=XY$; si realizza con due half adder e una OR. Il ripple carry adder a $n$ bit concatena $n$ full adder: il riporto "ondeggia" dal LSB al MSB, quindi il ritardo cresce linearmente con $n$. È un circuito iterativo (gerarchico e regolare). Il moltiplicatore a 2 bit usa 4 AND e 2 half adder.Sommatori binari - half adder, full adder e ripple carry →) lavora su numeri senza segno. Come rappresentare i numeri negativi, in modo che lo stesso circuito faccia somme e sottrazioni? La risposta è il complemento a 2. (Un'altra trattazione è in Rappresentazione dei numeri interi con segnoInteri con segno su n bit: modulo e segno, complemento a 1, complemento a 2 ed eccesso K; intervalli rappresentabili, calcolo dell'opposto, estensione del segno.Rappresentazione dei numeri interi con segno → e Aritmetica binariaSomma e sottrazione in binario, overflow per senza segno (riporto) e per complemento a 2 (segni), flag del processore, moltiplicazione per somme e scorrimenti, algoritmo di Booth, divisione, shift logici e aritmetici.Aritmetica binaria →.)

Sottrazione di numeri senza segno

Si sottrae NN da MM (entrambi su nn bit) bit per bit con i prestiti (Basi di numerazione e conversioni - binario, ottale ed esadecimaleUn numero in base $r$ vale $\sum a_i r^i$ (cifre $a_i\in{0,\dots,r-1}$). Conversioni: base $r\to$ decimale con la somma pesata; decimale $\to$ base $r$ per divisioni successive (parte intera, resti letti dal basso) e moltiplicazioni successive (parte frazionaria, parti intere lette dall'alto); binario $\leftrightarrow$ ottale/esadecimale a gruppi di 3/4 bit. Somma, differenza e prodotto binari seguono le regole decimali con cifre 0 e 1; la differenza ha prestiti, il prodotto somma prodotti parziali traslati.Basi di numerazione e conversioni - binario, ottale ed esadecimale →).

  • Se M≥NM\ge N: nessun prestito in uscita dal bit più significativo, e il risultato è corretto.
  • Se M<NM<N: c'è un prestito in uscita e il risultato è M−N+2nM-N+2^n, sbagliato. Il valore assoluto corretto è 2n2^n meno il risultato ottenuto (il suo complemento a 2), e il segno è negativo.

Esempio (n=8n=8): 01100100−1001011001100100-10010110 (100−150100-150). Il risultato a 8 bit è 1100111011001110 (206=100−150+256206=100-150+256), con prestito in uscita 11 (M<NM<N). Valore assoluto: 256−206=50=00110010256-206=50=00110010. Risultato corretto: −001100102=−50-00110010_2=-50.

Altro esempio con M≥NM\ge N: 10011011−0100111010011011-01001110 (155−78155-78) =01001101=01001101 (7777), nessun prestito.

Complementi

Definizione (complemento a 1 e a 2). Dato NN su nn bit:

  • complemento a 1: (2n−1)−N(2^n-1)-N, cioè il complemento di ogni bit (si scambiano 0 e 1);
  • complemento a 2: 2n−N2^n-N, cioè complemento a 1 più 1.

Esempio. N=1011001N=1011001 su 77 bit: complemento a 1 =0100110=0100110 (bit invertiti), complemento a 2 =0100110+1=0100111=0100110+1=0100111.

NN complemento a 1 complemento a 2
10110011011001 01001100100110 01001110100111
00011110001111 11100001110000 11100011110001
101100101100 010011010011 010100010100

Il complemento del complemento restituisce NN. Per 00 il complemento a 2 su nn bit è ancora 00 (si scarta il riporto).

Sottrazione con il complemento a 2. Poiché M−N=M+(2n−N)−2nM-N=M+(2^n-N)-2^n, si somma a MM il complemento a 2 di NN e si toglie 2n2^n:

  • se M≥NM\ge N la somma produce un riporto in uscita (il termine 2n2^n), che si scarta: resta M−NM-N;
  • se M<NM<N non c'è riporto in uscita e la somma vale 2n−(N−M)2^n-(N-M), il complemento a 2 della differenza: per ottenere il modulo si ripete il complemento a 2, e si mette il segno meno.

In questo modo la stessa addizione serve per sommare e sottrarre; con i numeri in complemento a 2 (sotto) l'ultimo passaggio sparisce.

Rappresentare numeri con segno

Si vedono due rappresentazioni a nn bit.

Segno e modulo. Si antepone un bit di segno: 00 per positivi (e zero), 11 per negativi. Un numero e il suo opposto differiscono solo per il bit di segno. Con 4 bit: da −7-7 a +7+7, ma lo zero ha due rappresentazioni (00000000 e 10001000). Le operazioni trattano segno e modulo separatamente, quindi la sottrazione richiede una correzione di segno.

Definizione (numeri con segno in complemento a 2). I positivi sono come in senza segno (00 seguito dal modulo); un negativo −N-N si rappresenta con il complemento a 2 di NN, cioè 2n−N2^n-N. L'MSB è 00 per tutti i positivi e 11 per tutti i negativi. Con 4 bit:

bit senza segno segno e modulo complemento a 2
0000 0 +0+0 0
0111 7 7 7
1000 8 −0-0 −8-8
1001 9 −1-1 −7-7
1010 10 −2-2 −6-6
1011 11 −3-3 −5-5
1100 12 −4-4 −4-4
1101 13 −5-5 −3-3
1110 14 −6-6 −2-2
1111 15 −7-7 −1-1

Esempio. A 88 bit −13=28−13=243=11110011-13=2^8-13=243=11110011.

Proprietà (intervallo e peso dell'MSB in complemento a 2). In complemento a 2 c'è un solo zero e l'intervallo è asimmetrico: da −2n−1-2^{n-1} a 2n−1−12^{n-1}-1 (con 8 bit da −128-128 a 127127; −(−128)-(-128) non è rappresentabile). Il valore si legge dando all'MSB il peso −2n−1-2^{n-1}: 11110011=−128+64+32+16+2+1=−1311110011=-128+64+32+16+2+1=-13.

Esempio. A 44 bit l'intervallo è da −8-8 a +7+7; 1011=−8+2+1=−51011=-8+2+1=-5.

Esempi a 8 bit: +9=00001001+9=00001001; −9-9: segno e modulo 1000100110001001, complemento a 2 1111011111110111 (=256−9=256-9: si inverte 00001001→1111011000001001\to11110110 e si somma 1). −13-13: segno e modulo 1000110110001101, complemento a 2 1111001111110011. Il numero −3-3 a 8 bit in complemento a 2 è 1111110111111101. Estensione del segno: per aumentare i bit di un numero in complemento a 2 si replica l'MSB (1101→111111011101\to11111101 resta −3-3).

I calcolatori usano il complemento a 2 perché somma e sottrazione condividono lo stesso hardware.

Somma e sottrazione con segno in complemento a 2

Somma: si sommano i numeri inclusi i bit di segno e si scarta il riporto in uscita dal bit di segno. Il risultato è in complemento a 2. Esempi a 8 bit:

operazione operandi risultato valore
+6+13+6+13 00000110+0000110100000110+00001101 0001001100010011 +19+19
−6+13-6+13 11111010+0000110111111010+00001101 0000011100000111 +7+7
+6−13+6-13 00000110+1111001100000110+11110011 1111100111111001 −7-7
−6−13-6-13 11111010+1111001111111010+11110011 1110110111101101 −19-19

Formula (sottrazione in complemento a 2). A−B=A+(−B)A-B=A+(-B), cioè si somma ad AA il complemento a 2 di BB: A−B=A+B‾+1A-B=A+\overline B+1 (complemento a 1 di BB più 1). Esempio: +7−(−12)+7-(-12): −12=11110100-12=11110100, il suo complemento a 2 è 0000110000001100 (+12+12), e 00000111+00001100=00010011=+1900000111+00001100=00010011=+19 ✓.

Esempio. A 44 bit, 5−35-3: 0101+0011‾+1=0101+1100+1=(1) 0010=+20101+\overline{0011}+1=0101+1100+1=(1)\,0010=+2, riporto scartato.

Circuito addizionatore-sottrattore

Con un solo circuito si fanno entrambe le operazioni: si introduce un segnale SS (0 = somma, 1 = sottrazione). Ogni bit BiB_i passa per una porta XOR con SS: se S=0S=0 passa BiB_i, se S=1S=1 passa Bi‾\overline{B_i} (complemento a 1). Lo stesso segnale SS è il riporto in ingresso del primo full adder, e fornisce il "+1". Il sommatore calcola quindi A+BA+B (con S=0S=0) oppure A+B‾+1=A−BA+\overline B+1=A-B (con S=1S=1). Per n=4n=4: quattro XOR, quattro full adder in cascata.

Overflow

L'overflow (straripamento) si ha quando il risultato non sta nei bit disponibili: per esempio 1000+1000=100001000+1000=10000 con numeri a 4 bit. È un problema in ogni sistema con un numero di bit fissato; il sistema deve poterlo rilevare.

Numeri senza segno.

  • Nella somma c'è overflow se il riporto in uscita dal bit più significativo vale 1.
  • Nella sottrazione non può esserci overflow (il risultato non supera il minuendo); il riporto in uscita dell'addizionatore-sottrattore vale C=1C=1 se M≥NM\ge N (risultato corretto) e C=0C=0 se M<NM<N (risultato da correggere con complemento e segno meno). Equivalente al "prestito" invertito.

Proprietà (overflow in complemento a 2). Somma e sottrazione di operandi di segno diverso non hanno mai overflow (il modulo non cresce). Si ha overflow solo se i due addendi (per la sottrazione: AA e −B-B) hanno lo stesso segno e il risultato ha segno opposto. In termini di riporti: c'è overflow se il riporto che entra nel bit di segno è diverso dal riporto che esce dal bit di segno: V=Cin, MSB⊕Cout, MSB.V=C_{in,\,MSB}\oplus C_{out,\,MSB}.

Esempio. A 44 bit 5+45+4: 0101+0100=10010101+0100=1001, riporto entrante nel segno 11, uscente 00, quindi V=1V=1 (il risultato 10011001 sarebbe −7-7).

Perché: se i due positivi sommano oltre 2n−1−12^{n-1}-1, il riporto entra nel bit di segno (che diventa 1) ma non esce; se i due negativi scendono sotto −2n−1-2^{n-1}, il riporto non entra ma esce. Con V=1V=1 il risultato è errato.

Esempi a 8 bit (intervallo −128…127-128\dots127):

  • 70+8070+80: 01000110+01010000=1001011001000110+01010000=10010110; riporto in ingresso al segno 11, in uscita 00 ⇒\Rightarrow V=1V=1: 150150 non sta, il risultato è letto come −106-106.
  • (−70)+(−80)(-70)+(-80): 10111010+10110000=(1) 0110101010111010+10110000=(1)\,01101010; riporto in ingresso 00, in uscita 11 ⇒\Rightarrow V=1V=1: −150-150 non sta, letto come +106+106.
  • 100+27=127100+27=127: 01100100+00011011=0111111101100100+00011011=01111111, riporti 00 e 00 ⇒V=0\Rightarrow V=0 (al limite, ma corretto).
  • (−100)+(−28)=−128(-100)+(-28)=-128: 10011100+11100100=(1) 1000000010011100+11100100=(1)\,10000000, riporti 11 e 11 ⇒V=0\Rightarrow V=0 (corretto).

Esercizi di riferimento (numeri in complemento a 2, MSB = segno):

  • (a) 110001+011101110001+011101 (6 bit: −15+29-15+29): somma 001110001110, riporto in ingresso al segno 11, in uscita 11 ⇒\Rightarrow nessun overflow; risultato +14+14 ✓.
  • (b) 0110111+01011110110111+0101111 (7 bit: +55+47+55+47): somma 11001101100110; riporto in ingresso al segno 11, in uscita 00 ⇒\Rightarrow overflow (102>63102>63).
  • (c) 00000111−1111010000000111-11110100 (+7−(−12)+7-(-12)): 00000111+00001100=0001001100000111+00001100=00010011 ⇒\Rightarrow nessun overflow, +19+19.
  • (d) 0110111−01011110110111-0101111 (+55−47+55-47, 7 bit): complemento a 2 del sottraendo 10100011010001; 0110111+1010001=(1) 00010000110111+1010001=(1)\,0001000; riporti 11 e 11 ⇒\Rightarrow nessun overflow; +8+8 (il riporto in uscita si scarta).

VHDL

Con il package numeric_std il tipo signed rappresenta numeri in complemento a 2:

vhdl
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity add_signed is
  port ( a, b : in  std_logic_vector(7 downto 0);
         s    : out std_logic_vector(7 downto 0);
         v    : out std_logic );                    -- overflow
end add_signed;

architecture beh of add_signed is
  signal sum : std_logic_vector(7 downto 0);
begin
  sum <= std_logic_vector(signed(a) + signed(b));
  s   <= sum;
  v   <= (a(7) xnor b(7)) and (a(7) xor sum(7));    -- stesso segno in ingresso, segno diverso in uscita
end beh;

Il package fa interpretare i vettori come numeri con segno; con un package come std_logic_unsigned gli stessi vettori sarebbero senza segno (Introduzione al VHDL - entity, architecture, tipi e livelli di descrizioneVHDL è un linguaggio di descrizione dell'hardware (HDL), non di programmazione: le dichiarazioni sono concorrenti e descrivono blocchi di circuito; serve per documentare, simulare e sintetizzare. Un blocco ha una entity (nome e porte in/out) e almeno una architecture (cosa c'è dentro: structural con component e port map, dataflow con equazioni booleane, behavioral con comportamento). Tipi: std_logic (da 1164: '0','1','X','Z','U','-',...), std_logic_vector, bit, boolean, integer. Signal per i collegamenti interni, constant per i valori fissi.Introduzione al VHDL - entity, architecture, tipi e livelli di descrizione →).

Errori comuni

  • Dire che in complemento a 2 il riporto in uscita indica overflow: per i numeri con segno conta il confronto tra il riporto entrante e quello uscente dal bit di segno.
  • Calcolare il complemento a 2 invertendo i bit senza sommare 1.
  • Credere che −(−2n−1)-(-2^{n-1}) sia rappresentabile: l'intervallo è asimmetrico.
  • Usare l'estensione con zeri (anziché replicare il segno) su un numero negativo.
  • Scrivere −13-13 a 8 bit come 1000110110001101 (è segno e modulo): in complemento a 2 è 1111001111110011.
  • Segno del risultato nella sottrazione senza segno: se c'è prestito va corretto con complemento e segno meno.

Versione ripasso

  • Sottrazione senza segno: se M≥NM\ge N non c'è prestito in uscita e il risultato è corretto. Se M<NM<N il risultato M−N+2nM-N+2^n è sbagliato: il valore assoluto è 2n2^n meno il risultato, con segno negativo. Esempio (n=8n=8): 01100100−10010110=1100111001100100-10010110=11001110 con prestito; 256−206=50256-206=50, quindi −50-50.
  • Complementi: a 1 =(2n−1)−N=(2^n-1)-N (si invertono i bit); a 2 =2n−N=2^n-N = complemento a 1 più 1. Esempio: 1011001→0100110→01001111011001\to0100110\to0100111. Il complemento del complemento restituisce NN.
  • Numeri con segno: segno e modulo ha due zeri (00000000 e 10001000) e intervallo simmetrico. Complemento a 2 ha un solo zero, intervallo da −2n−1-2^{n-1} a 2n−1−12^{n-1}-1, e l'MSB pesa −2n−1-2^{n-1}: 11110011=−128+64+32+16+2+1=−1311110011=-128+64+32+16+2+1=-13; su 4 bit 1011=−51011=-5. Estensione del segno: 1101→111111011101\to11111101 resta −3-3.
  • Somma: si sommano tutti i bit, incluso il segno, e si scarta il riporto in uscita dal bit di segno. Esempio: +6−13+6-13: 00000110+11110011=11111001=−700000110+11110011=11111001=-7; −6−13-6-13: 11111010+11110011=11101101=−1911111010+11110011=11101101=-19.
  • Sottrazione: A−B=A+B‾+1A-B=A+\overline B+1, quindi A−BA-B usa lo stesso sommatore con S=1S=1: XOR su ogni bit di BB e SS come riporto in ingresso. Esempio: +7−(−12)=00000111+00001100=00010011=+19+7-(-12)=00000111+00001100=00010011=+19.
  • Overflow senza segno: nella somma c'è overflow se Cout=1C_{out}=1.
  • Overflow con segno: V=Cin,MSB⊕Cout,MSBV=C_{in,MSB}\oplus C_{out,MSB}. Operandi di segno diverso non danno mai overflow. Esempi a 8 bit: 70+80=1001011070+80=10010110 con V=1V=1 (150 non sta nell'intervallo); −100−28=−128-100-28=-128 con V=0V=0; +55+47+55+47 su 7 bit ha overflow.
  • VHDL: sum <= std_logic_vector(signed(a) + signed(b)); e overflow v <= (a(7) xnor b(7)) and (a(7) xor sum(7)); (Introduzione al VHDL - entity, architecture, tipi e livelli di descrizioneVHDL è un linguaggio di descrizione dell'hardware (HDL), non di programmazione: le dichiarazioni sono concorrenti e descrivono blocchi di circuito; serve per documentare, simulare e sintetizzare. Un blocco ha una entity (nome e porte in/out) e almeno una architecture (cosa c'è dentro: structural con component e port map, dataflow con equazioni booleane, behavioral con comportamento). Tipi: std_logic (da 1164: '0','1','X','Z','U','-',...), std_logic_vector, bit, boolean, integer. Signal per i collegamenti interni, constant per i valori fissi.Introduzione al VHDL - entity, architecture, tipi e livelli di descrizione →).
  • Errori: overflow letto dal solo riporto; complemento a 2 senza il +1+1; −13-13 scritto come 1000110110001101 (è segno e modulo: in complemento a 2 è 1111001111110011); −(−2n−1)-(-2^{n-1}) creduto rappresentabile.
  • Sottrazione senza segno con prestito: in ogni colonna con prestito si aggiunge 2 alla cifra. Esempio: 101102−100112=000112=310110_2-10011_2=00011_2=3, letto dal bit 0 al bit 4 con cifre 1,1,0,0,01,1,0,0,0 e prestiti tra le colonne 0, 1 e 2.
  • Complemento a 2 su 4 bit: 0111=70111=7, 1000=−81000=-8, 1001=−71001=-7, 1011=−51011=-5, 1111=−11111=-1.
  • Esempi a 8 bit: +9=00001001+9=00001001; −9=11110111-9=11110111 (si inverte 0000100100001001 e si somma 1); −13=11110011-13=11110011.
  • Addizionatore-sottrattore: un segnale SS fa XOR su ogni bit di BB e diventa il riporto in ingresso del primo full adder: S=0S=0 somma, S=1S=1 sottrae.
  • Overflow, esercizi: 110001+011101110001+011101 su 6 bit (−15+29-15+29) non ha overflow e dà +14+14; 0110111+01011110110111+0101111 su 7 bit (+55+47+55+47) ha overflow, perché 102>63102>63.
  • Estensione del segno: si replica l'MSB, così il valore non cambia.

Esercizi su questo argomento

Teoria collegata