2016-05-25 19 views
5

Attualmente sto leggendo un libro sulla programmazione C# e ho introdotto brevemente Overflow e Underflow e lo scrittore dà un'idea generale di cosa succede quando si supera l'intervallo consentito di un certo tipo.Qualcuno può spiegare l'overflow in C# usando il binario?

Esempio

short a = 30000; 
short b = 30000; 
short sum = (short)(a + b); // Explicitly cast back into short 
Console.WriteLine(sum); // This would output the value -5536 

Così il tipo corto ha solo una gamma di -32.768-32.767 e nel libro la spiegazione fornita dallo scrittore è "Per i tipi interi (byte, short, int, e lungo), i bit più significativi (che vengono inondati) vengono rilasciati, in particolare quando il computer lo interpreta come un involucro, per questo nel nostro esempio si finisce con un valore negativo. si inizia con il valore massimo per un tipo particolare (ad esempio, short.MaxValue) e ne si aggiunge uno ad esso. " C# Players Guide Seconda edizione, capitolo 9, pagina 58

si finirebbe al minimo (-32768).

Sto avendo un problema comprensione di questo mi confondo quando lo scrittore parla di "il computer lo interpreta come avvolgere intorno"

Il modo in cui ho provato capire che questo era che il tipo corto utilizza 2 byte (16 bit)

così il numero 32767 = 0111111111111111 se ero a +1 alla stringa binaria avrei finire con 32768 = 1.000.000 miliardi (che non può essere rappresentato con il tipo corto come valore massimo è 32767) così la il compilatore dà -32768. Perché finisce come negativo?

Ho compreso il concetto di utilizzo di due complimenti per rappresentare numeri negativi e qualcuno potrebbe correggere il mio pensiero qui o elaborato perché non capisco completamente perché utilizziamo solo 15 bit dei 16 bit per rappresentare il range positivo e il più bit significativo per il range negativo

+1

Stai dimenticando di tenere conto del bit del segno. –

+0

Non capisco :(, potresti spiegare per favore? – Shabubble

+0

Sui valori firmati, un bit (l'MSB) è riservato come bit di segno, per indicare se il numero è positivo o negativo.Come altro potresti dire se il numero era negativo o no? Non stai considerando quel bit che deve essere presente. –

risposta

16

Ignora tutti quelli che ti dicono che il bit in alto è un bit di segno. Questo è il modo sbagliato di pensarci.

Il modo giusto per pensare a questo proposito è:

  • Abbiamo 65536 possibili schemi di bit.
  • Pertanto possiamo rappresentare 65536 possibili numeri.
  • Dobbiamo avere una mappa che assegna a a ciascun modello di bit.

Per pantaloncini firmati, assegniamo i modelli di punta come segue:

0000000000000000 --> 0 
0000000000000001 --> 1 
... 
0111111111111111 --> 32767 
1000000000000000 --> 32768 
1000000000000001 --> 32769 
... 
1111111111111111 --> 65535 

Per firmato pantaloncini, si usa la seguente convenzione:

0000000000000000 --> 0 
0000000000000001 --> 1 
... 
0111111111111111 --> 32767 
1000000000000000 --> -32768 
1000000000000001 --> -32767 
... 
1111111111111111 --> -1 

Semplice come quello.

Perché utilizziamo questa convenzione?

tre motivi:

(1) I primi 32K valori sono gli stessi se si sta con o senza segno. È molto conveniente

(2) In entrambe le convenzioni, "tutti i bit zero" significa zero.

(3) Perché le aggiunte funzionano esattamente allo stesso modo in entrambe le convenzioni!

Abbiamo

0000000000000000 --> 0 

e vogliamo aggiungere uno. Ne aggiungiamo uno usando le regole binarie e otteniamo:

0000000000000001 --> 1 

Questo funziona sia che il corto sia firmato o non firmato.

Abbiamo unsigned short:

1000000000000000 --> 32768 

vogliamo aggiungere uno. Lo facciamo usando le regole binarie, e otteniamo la risposta giusta:

1000000000000001 --> 32769 

Stesso per i pantaloncini firmati. Abbiamo

1000000000000000 --> -32768 

e desideriamo aggiungerne uno. Lo facciamo con le regole binari e otteniamo:

1000000000000001 --> -32767 

Allo stesso modo, è possibile verificare che con l'aggiunta di 1111111111111111 a qualsiasi numero binario, si ottiene "uno di meno", e quindi la sottrazione di una funziona così come l'aggiunta di uno . È quindi possibile continuare a mostrare che, in generale, addizione e sottrazione funzionano allo stesso modo sia in aritmetica firmata che senza segno, il che significa che il processore non deve sapere se il compilatore pensa che i valori siano firmati o non firmati.

Ecco perché utilizziamo due complementi: perché la matematica sottostante è esattamente la stessa sia che si esegua l'aritmetica con segno o senza segno.

Si noti che non ho detto nulla di un "segno" in là. Il fatto che il bit più alto sia impostato per i numeri negativi è solo un bel bonus. La proprietà reale che vogliamo è solo costruire hardware per fare matematica una volta.

Il complemento Twos è solo una convenzione per l'assegnazione di uno dei due possibili significati ai modelli di bit in base al tipo associato alla variabile che tiene il modello di bit. Come industria, abbiamo scelto questa convenzione perché è economico creare hardware ad alte prestazioni che utilizzi questa convenzione.

Ci sono molte altre convenzioni che avremmo potuto scegliere. Per esempio, avremmo potuto detto che per i numeri con segno usiamo la mappa:

0000000000000000 --> -32768 
0000000000000001 --> -32767 
... 
0111111111111111 --> -1 
1000000000000000 --> 0 
1000000000000001 --> 1 
... 
1111111111111111 --> 32767 

Si noti che questo è esattamente lo stesso di prima, tranne per il bit top!

In questa interpretazione, l'aggiunta funziona ancora come previsto. Ma questa mappa non ha la proprietà che i primi 32K valori siano gli stessi tra breve e ushort, e non ha la proprietà che tutti i bit zero significano zero. Quindi non usiamo questa convenzione, perché è meno conveniente. In questa convenzione, la conversione da short a ushort richiederebbe un'aggiunta. Impostare un cortocircuito su zero richiede l'impostazione dei byte su qualcosa diverso da zero. Potremmo usare una convenzione in cui i numeri firmati erano "in ordine", semplicemente non lo facciamo perché è doloroso farlo.

+0

Una buona spiegazione ha molto più senso :) Sto avendo problemi a capire "I primi valori 32K sono gli stessi sia che tu sia firmato o non firmato". – Shabubble

+0

Aspetta penso di sapere 1000000000000000 -> 32768 e 1000000000000000 -> -32768 hanno entrambi lo stesso schema di bit, non l'ho visto prima di – Shabubble

+0

@Shabubble: qual è il pattern di bit per 123 in un corto firmato? Qual è il pattern di bit per 123 in un corto senza segno? Loro sono la stessa cosa. In realtà sono tutti uguali, fino a 32767. –

Problemi correlati