Domanda

In un compilatore TC ++, la rappresentazione binaria di 5 è (00000000000000101) . So che i numeri negativi sono memorizzati come complemento di 2, quindi -5 in binario è (111111111111011) . Il bit più significativo (bit di segno) è 1 che indica che è un numero negativo.

Quindi, come fa il compilatore a sapere che è -5 ? Se interpretiamo il valore binario indicato sopra (111111111111011) come un numero senza segno, risulterà completamente diverso?

Inoltre, perché il complimento 1 di 5 -6 (1111111111111010) ?

È stato utile?

Soluzione

Il compilatore non lo sa . Se lanci -5 su unsigned int otterrai 32763 .

Altri suggerimenti

Il compilatore lo sa perché questa è la convenzione che la CPU usa in modo nativo. Il tuo computer ha una CPU che memorizza numeri negativi nella notazione del complemento a due, quindi il compilatore segue l'esempio. Se la tua CPU supporta la notazione del complemento a uno, il compilatore lo userebbe (come nel caso dei float IEEE, per inciso).

L'articolo di Wikipedia sull'argomento spiega come funziona la complemento a due .

Il processore implementa istruzioni firmate e non firmate, che opereranno diversamente sulla rappresentazione del numero binario. Il compilatore sa quale di queste istruzioni emettere in base al tipo di operandi coinvolti (ovvero int vs. unsigned int ).

Il compilatore non ha bisogno di sapere se un numero è negativo o meno, emette semplicemente la macchina corretta o le istruzioni del linguaggio intermedio per i tipi coinvolti. L'implementazione di queste istruzioni da parte del processore o del runtime di solito non ha molta importanza se il numero è negativo o meno, poiché la formulazione dell'aritmetica del complemento a due è tale che è la stessa per i numeri positivi o negativi (in realtà, questo è il principale vantaggio dell'aritmetica del complemento a due). Ciò che dovrebbe sapere se un numero è negativo sarebbe qualcosa come printf () , e come ha sottolineato Andrew Jaffe, l'MSBit impostato è indicativo di un numero negativo in complemento a due.

Il primo bit è impostato solo per numeri negativi (si chiama bit di segno)

Informazioni dettagliate sono disponibili qui

La parte kewl del complemento a due è che le istruzioni Aggiungi e Sottrai del linguaggio macchina possono ignorare tutto ciò, fare semplicemente l'aritmetica binaria e funziona ...

cioè -3 + 4

nel complemento di Binary 2, è

   1111 1111 1111 1101   (-3)
+  0000 0000 0000 0100   ( 4)
   -------------------
   0000 0000 0000 0001   ( 1)

facciamo un esempio: abbiamo due numeri in due byte in binario: A = 10010111 B = 00100110 (notare che la macchina non conosce il concetto di firmato o non firmato in questo livello)

ora quando dici " aggiungi " questi due, cosa fa la macchina? aggiunge semplicemente:

R = 10111101 (e portare bit: 1)

ora, come compilatore, dobbiamo interpretare l'operazione. abbiamo due opzioni: i numeri possono essere firmati o non firmati.

1- caso senza segno: in c, i numeri sono di tipo "carattere senza segno"; e i valori sono 151 e 38 e il risultato è 189. questo è banale.

2 - caso firmato: noi, il compilatore, interpretiamo i numeri in base al loro msb e il primo numero è -105 e il secondo è ancora 38. quindi -105 + 38 = -67. Ma -67 è 10111101. Ma questo è ciò che abbiamo già nel risultato (R)! Il risultato è lo stesso, l'unica differenza è il modo in cui il compilatore lo interpreta.

La conclusione è che, indipendentemente da come consideriamo i numeri, la macchina fa la stessa operazione sui numeri. Ma il compilatore interpreterà i risultati a sua volta.

Nota che non è la macchina a conoscere il concetto di complemento di 2 . aggiunge solo due numeri senza preoccuparsi del contenuto. Il compilatore , quindi, esamina il bit del segno e decide .

Quando si tratta di sottrazione, anche questa volta l'operazione è unica: prendi il complemento di 2 del secondo numero e aggiungi i due.

Se il numero è dichiarato come tipo di dati con segno (e non digitare cast con un tipo senza segno), il compilatore saprà che, quando il bit di segno è 1, è un numero negativo. Per quanto riguarda il motivo per cui il complemento di 2 viene utilizzato al posto del complemento di 1, non vuoi essere in grado di avere un valore di -0, che il complemento di 1 ti consentirebbe di fare, quindi hanno inventato il complemento di 2 per risolverlo.

È esattamente quel bit più significativo - se sai che un numero è firmato, allora se l'MSB = 1 il compilatore (e il runtime!) sa interpretarlo come negativo. Questo è il motivo per cui le lingue di tipo c hanno numeri interi (positivi e negativi) e interi senza segno - in tal caso li interpreti tutti come positivi. Quindi un byte con segno va da -128 a 127, ma un byte senza segno da 0 a 255.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top