2010-09-01 8 views
56

Non capisco perché il valore minimo che un byte può assumere sia -128. Vedo che il valore più alto è 127, perché è 01111111 in binario, ma come si rappresenta -128 con solo 8 bit, uno dei quali è utilizzato per il segno? Il 128 positivo sarebbe già a 8 bit, ovvero 10000000, e quindi sarebbe necessario un nono bit per rappresentare il segno negativo.Perché l'intervallo di byte da -128 a 127 in Java?

Qualcuno potrebbe aiutarmi a spiegarmi questo.

+19

[di due si completano] (http: //en.wikipedia.org/wiki/Two's_complement) –

+1

È simile per gli altri tipi interi 'short',' int' e 'long'. – starblue

+6

Una domanda migliore è 'perché il tipo di byte java non è un intervallo di 0..255'? In effetti molti fanno questa domanda, nella maggior parte delle lingue il 'byte' non è firmato, ma anche java' byte' è firmato, e io (e molti altri) credo che sia stato un cattivo progetto rimasto in Java dal primo giorno. Ci sono problemi quando si lavora con JNI, e credetemi quando date un nome a 'byte' che volete 0..255! –

risposta

63

La risposta è two's complement.

In breve, Java (e la maggior parte dei linguaggi moderni) non rappresentano interi con segno utilizzando la rappresentazione della magnitudine firmata. In altre parole, un numero intero a 8 bit non è un bit di segno seguito da un numero intero senza segno a 7 bit.

Invece, gli interi negativi sono rappresentati in un sistema chiamato complemento a due, che consente una più facile elaborazione aritmetica nell'hardware, ed elimina anche la potenziale ambiguità di avere zero positivi e zero negativi. Un effetto collaterale dell'eliminazione dello zero negativo è che c'è sempre un numero negativo in più disponibile nella parte inferiore dell'intervallo.

Un'altra proprietà interessante dei due del sistema del complemento è che il primo bit fa efficacemente funzione come indicatore segno (cioè tutti i numeri che iniziano con il bit 1 sono negativi), ma i successivi sette bit non devono essere interpretate sulla loro proprio come un numero senza segno a cui viene applicato il bit di segno.

Il complemento a due non è terribilmente complicato, ma ottenere una buona presa iniziale su cosa sia il complemento a due e come e perché funzioni è probabilmente oltre lo scopo di una risposta SO. Inizia con l'articolo di Wikipedia o usa il termine per altre risorse.

Per provare a rispondere brevemente alla domanda su -128, l'idea fondamentale dietro la generazione del numero di complemento a due è di prendere la forma senza segno del numero, invertire tutti i bit e aggiungerne uno. Quindi 128 senza segno è 10000000. Invertito, è 01111111 e l'aggiunta di una ottiene di nuovo 10000000. Quindi, nel sistema a complemento a due, 10000000 è inequivocabile -128 e non +128. I numeri maggiori o uguali a +128 semplicemente non possono essere rappresentati in 8 bit usando un sistema a complemento a due perché sarebbero ambigui con le forme dei numeri negativi.

+0

Neat! Vediamo se ho capito bene: è ancora vero che i numeri a 8 bit che iniziano con 0 (diverso da 00000000) SONO positivi e iniziano con 1 ARE negativo? Inoltre, l'unica cosa veramente complicata sul complemento a due è che la rappresentazione bit dei byte non ha lo stesso valore che fanno in una classe matematica, cioè 10000000 è normalmente +128, ma come byte è -128. Amirite? –

+0

Hai ragione. Il primo bit è 1 se e solo se il numero è negativo. Se il primo bit è 0, il numero è positivo o zero. –

+0

@Tyler: Scommetto che potrebbe rispondere alla mia domanda in questo post così: http://stackoverflow.com/questions/16775169/java-binary-literals-value-128-for-byte Spero che questo sia non troppo diretto, ma mi chiedo davvero e dopo alcuni mesi di ricerche sporadiche non ho ancora idea: ~ – JBA

8

Come James ha sottolineato nel suo commento, è perché è così che funziona il complemento a due.

Se lo inseriamo in altri termini, puoi rappresentare 2^8 = 256 tipi di valori. che è, in questo caso, utilizzato come 128 numeri negativi, 127 numeri positivi e zero. Se usassimo 7 bit per rappresentare il valore, +1 bit per un segno, potremmo rappresentare un valore in meno e avremmo anche due zeri (il che sarebbe molto spiacevole in quanto il confronto di due valori sarebbe più complicato a causa di ciò).

1

in java tutte le variabili come byte short int long float double sono scritte come firmate. quindi è molto semplice il bit della testa specifica sempre cosa è (negativo o positivo), ma poiché i numeri sono divisibili per 2 metà è spostato come negativo, 0 è positivo per impostazione predefinita. in modo che appaia in questo modo:

questo è positivo
+ | 0.001.001
1 | 0.001.001
questo è negativo
- | 0.001.001
0 | 0.001.001
come un byte breve un negativo è
-000000011111111

3

ty numerica di base pes può rappresentare 2^n numeri. Guarda un caso n = 2. Puoi rappresentare quattro casi, chiamiamoli a, b, c, d. Quindi è possibile accettare o a=-2, b=-1, c=0, d=1 (questo è il modo accettato) o a=-1, b=0, c=1, d=2 (possibile, ma non utilizzato). Quindi, se hai solo uno zero e tieni premuto 2^n, il tuo abs(min) != max Aumentando lo n sposta i bordi, ma abs(min) != max rimane ancora.

1

byte consiste di 8 bit ---> 1 bit di segno (positivo o negativo) il valore 7 bit

quindi l'intervallo -2^7 negativo (-128) a 2^7 -1 positivo (127)

0

Senza entrare in complemento a due: 2^8 (poiché un byte è 8 cifre e può avere 1 su 2 valori) = 256, in modo più singoli valori di byte può rappresentare è 256. così, che rappresentano i numeri -128 a -1 è metà del nostro raggio d'azione. Credo che la domanda qui sia perché è il valore positivo massimo 127 piuttosto che 128. Questo perché dobbiamo rappresentare il numero 0, quindi in modo inclusivo 0-127 sono le altre 128 possibilità del nostro intervallo.

Se si consentivano solo valori positivi, ad esempio un byte senza segno dove non sono possibili numeri negativi, l'intervallo sarebbe 0-255, poiché si tratta di 256 valori diversi (compreso lo 0).

6

Oltre alle risposte qui, posso spiegare come funziona il complemento a due.

Un byte è composto da 8 bit.

00000000 significa 0

11111111 significa 255

Tuttavia, se solo diciamo così, non possiamo distinguere se il numero positivo o negativo è. Per questo motivo, il bit sul lato sinistro ci fornisce questa informazione. Se il bit sul lato sinistro è 0, puoi iniziare ad aggiungere il valore di altri bit nella parte superiore dello zero. Se il bit è 1, dovresti iniziare ad aggiungere nella parte superiore di -128. Perché il bit sul lato sinistro è due alla potenza di sette.

Esempi;

In questi esempi, il bit sul lato sinistro è 1, significa che stiamo aggiungendo i valori di altri bit nella parte superiore di -128.

10000000 = -128 (-128 + 0)

10000001 = -127 (-128 + 1)

10000011 = -125 (-128 + 3)

10000111 = -121 (-128 + 7)

Stesse byte, ma questa volta, il bit a sinistra è 0. ciò significa, stiamo iniziando aggiungere sulla parte superiore del 0.

00000000 = 0 (0 + 0)

00000001 = 1 (0 + 1)

00000011 = 3 (0 + 3)

00000111 = 7 (0 + 7)

Se siamo ok fino ad ora, la risposta alla tua domanda, il numero più piccolo possibile con 8 bit con questa regola è;

10000000 = -128

il maggior numero possibile

011111111 = 127

Questo è il motivo per cui, l'intervallo è compreso tra -128 e 127.