Calcolo del complemento a due (conversione binaria degli interi con segno)

Converte un numero decimale con segno nella configurazione di bit in complemento a due su 8, 16, 32 o 64 bit, e viceversa. Mostra anche l'interpretazione come intero senza segno, la notazione esadecimale e rileva i valori fuori intervallo.

Che cos'è il complemento a due

Il complemento a due è il metodo con cui i computer rappresentano gli interi con segno — numeri che possono essere positivi o negativi — come semplici sequenze di bit. I numeri positivi vengono memorizzati come normale binario, mentre un numero negativo si ottiene invertendo tutti i bit del suo valore assoluto e sommando poi uno. Il bit più significativo (MSB) funge anche da indicatore di segno: 1 significa negativo, 0 significa positivo, e l'intervallo rappresentabile dipende dall'ampiezza in bit scelta (8, 16, 32 o 64 bit).

Questo strumento converte un numero decimale con segno nella sua configurazione binaria in complemento a due secondo l'ampiezza scelta, e può anche convertire nel senso opposto, da una stringa binaria a un decimale. Accanto al risultato principale mostra l'interpretazione senza segno degli stessi bit, la notazione esadecimale e un confronto con la rappresentazione in segno e modulo, così da vedere concretamente come la stessa sequenza di bit possa significare cose diverse a seconda di come viene letta.

Come usare il calcolo del complemento a due

  1. Scegliete l'ampiezza in bit Selezionate 8, 16, 32 o 64 bit in base al tipo di intero che volete controllare.
  2. Scegliete il verso della conversione Passate da "decimale → binario" a "binario → decimale" a seconda di ciò che dovete convertire.
  3. Inserite un valore Digitate un intero decimale con segno (per esempio -5) oppure una sequenza binaria (per esempio 11111011).
  4. Leggete il risultato della conversione Il valore decimale con e senza segno, la configurazione in complemento a due e la notazione esadecimale compaiono insieme.
  5. Controllate l'avviso di intervallo o traboccamento Inserite un valore fuori da ciò che l'ampiezza in bit può contenere per vedere esattamente dove si trova il limite del traboccamento.

Consigli per sfruttarlo al meglio

  • Un intero con segno a 8 bit copre l'intervallo da -128 a 127. Provate a inserire 127 e poi 128 per osservare il punto in cui, sommando uno a 127, si trabocca e si torna a -128: il valore 128 dà errore, ed è esattamente il confine del traboccamento.
  • La riga del decimale senza segno mostra il valore che si ottiene leggendo la stessa sequenza come un semplice intero, senza bit di segno. Confrontandola con un valore negativo si coglie a colpo d'occhio la differenza fra le due interpretazioni.
  • Il numero binario inserito deve avere esattamente tante cifre quanta è l'ampiezza scelta: otto cifre per 8 bit, sedici per 16 bit.
  • Il calcolo a 64 bit perderebbe precisione con il tipo Number di JavaScript e si serve perciò internamente di BigInt: anche i valori vicini a due elevato alla sessantatreesima si convertono senza errori.
  • Lo strumento si presta anche come materiale didattico per comprendere il traboccamento degli interi nei tipi int, a 32 bit, e long, a 64 bit, del linguaggio C e di Java.

Impieghi pratici del complemento a due

Preparazione a corsi ed esami di informatica

Svolgete a mano gli esercizi di conversione binaria presenti in quasi tutti i corsi introduttivi di informatica e verificate le vostre risposte.

Individuare bug di traboccamento in C o nei sistemi embedded

Riproducete con l'ampiezza in bit reale un valore imprevisto di una variabile int o uint8_t per individuare con precisione l'origine dell'errore.

Capire come i registri della CPU memorizzano i valori

Quando un debugger mostra il valore esadecimale di un registro, verificate rapidamente quale intero con segno rappresenta davvero quella configurazione.

Verificare i risultati delle operazioni sui bit

Prima e dopo aver scritto la logica di AND, OR o scorrimento, confermate a mano che la configurazione ottenuta corrisponda a quanto previsto.

Glossario del complemento a due

Complemento a due
Un modo di rappresentare i numeri negativi invertendo tutti i bit del valore assoluto e sommando uno. Dà allo zero un'unica configurazione univoca e permette allo stesso circuito di addizione di gestire sia la somma sia la sottrazione, motivo per cui quasi ogni CPU moderna lo usa per gli interi con segno.
Bit di segno
Il bit più significativo (MSB) di una sequenza di bit. Nel complemento a due, il valore 1 indica che il numero è negativo e 0 che è positivo.
Traboccamento (overflow)
Ciò che accade quando un risultato non entra più nell'ampiezza in bit disponibile. Il bit più significativo in eccesso viene scartato, il che cambia il significato del bit di segno e fa apparire il valore come se saltasse all'estremo opposto dell'intervallo.
Intero con segno e senza segno
La stessa sequenza di bit può rappresentare due valori diversi a seconda che il bit di segno venga trattato come indicatore di numeri negativi (con segno) o semplicemente come un ulteriore bit di valore (senza segno).
Ampiezza in bit
Il numero di bit usati per memorizzare un intero. Le ampiezze più comuni sono 8, 16, 32 e 64 bit: più ampio è il tipo, più esteso è l'intervallo di valori rappresentabile.
Complemento a uno
Un metodo più antico che forma un numero negativo invertendo semplicemente tutti i bit del valore positivo, senza sommare 1. Ha lo svantaggio di produrre due configurazioni distinte per lo zero ("+0" e "-0"), un problema che il complemento a due è stato ideato per eliminare.

Domande frequenti

Nelle rappresentazioni in segno e modulo e in complemento a uno nascono due zeri distinti, un «più zero» e un «meno zero», che complicano i circuiti di confronto e di calcolo. Con il complemento a due la configurazione dello zero è una sola e il circuito di addizione si riusa direttamente per la sottrazione, semplificando l'unità aritmetico-logica del processore. Per questi due vantaggi quasi tutti i processori moderni lo adottano come rappresentazione interna degli interi con segno.

Va da -128 a 127. Poiché il bit più significativo esprime il segno, i valori positivi arrivano a 127, cioè sette bit, mentre i negativi coprono 128 possibilità, da -1 a -128: l'intervallo è dunque asimmetrico. Ciò accade perché il complemento a due ha un solo zero e la configurazione risparmiata va ad accrescere la capacità espressiva dal lato negativo.

Il complemento a uno ottiene il numero negativo semplicemente invertendo tutti i bit del positivo; il complemento a due vi somma poi uno. Il complemento a uno ha il difetto di produrre due zeri, 00000000 e 11111111, e proprio per eliminarlo si è affermata la rappresentazione con la somma di uno.

Perché l'ampiezza in bit è fissa: quando il risultato eccede l'intervallo rappresentabile, i bit più significativi vengono tagliati e il bit di segno cambia significato. Sommando uno al massimo 127 di un intero con segno a 8 bit si ottiene 10000000, che nell'interpretazione con segno vale -128. Superato il limite superiore si ricomincia dall'estremo inferiore: è questo comportamento controintuitivo la vera natura del traboccamento.

La sequenza di bit resta identica, ma il bit più significativo non viene letto come segno e concorre al valore: la stessa configurazione assume quindi un valore diverso. Per esempio 11111011 su 8 bit vale -5 con segno e 251 senza segno. Questa reinterpretazione avviene realmente quando si usano tipi privi di segno, come unsigned int nel linguaggio C.
Tool-kun

A proposito — perché gli elaboratori usano il complemento a due

Il complemento a due non è l'unico modo di rappresentare i numeri negativi con una sequenza di bit. Storicamente si sono usate anche la rappresentazione in segno e modulo, che riserva al segno il bit più significativo, e quella in complemento a uno, che si limita a invertire tutti i bit del numero positivo. Entrambe hanno però un difetto comune: esistono due configurazioni per lo zero, un «più zero» e un «meno zero», il che complica i confronti e la progettazione dei circuiti. Con il complemento a due il problema dei due zeri non si pone e la corrispondenza fra configurazione e zero è biunivoca.

Il vantaggio maggiore, però, è che lo stesso circuito di addizione serve anche per la sottrazione. Il processore non deve preoccuparsi se i numeri siano positivi o negativi: gli basta sommare le sequenze di bit per ottenere il risultato corretto, poiché sottrarre equivale a sommare il complemento. Non occorrendo né un circuito di sottrazione dedicato né una logica di riconoscimento del segno, l'unità aritmetico-logica si semplifica: è per questo che quasi tutte le architetture moderne adottano il complemento a due per gli interi con segno.

Anche il traboccamento è una conseguenza diretta di questa rappresentazione. Sommando uno a 127, cioè 01111111, in un intero con segno a 8 bit, il riporto produce semplicemente 10000000, ossia -128. Nel linguaggio C il traboccamento degli interi con segno è considerato comportamento indefinito e le ottimizzazioni del compilatore possono produrre esiti imprevisti: nella pratica occorre quindi prudenza con questi valori limite. In Java, per contro, la specifica stabilisce che il traboccamento avvenga silenziosamente, con un ritorno all'estremo opposto: una differenza interessante nel livello di garanzia offerto dai vari linguaggi.