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.

Consigli per l'uso

  • 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.

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.