ti-enxame.com

Por que o intervalo de bytes -128 a 127 em Java?

Eu não entendo porque o menor valor que um byte pode ter é -128. Eu posso ver que o valor mais alto é 127, porque é 01111111 em binário, mas como um deles representa -128 com apenas 8 bits, um dos quais é usado para o sinal? O positivo 128 já seria 8 bits, ou seja, 10000000, e então você precisaria de um 9º bit para representar o sinal negativo. 

Alguém poderia me ajudar a explicar isso para mim.

60
Bad Request

A resposta é complemento de dois .

Em suma, Java (e as linguagens mais modernas) não representam inteiros assinados usando representação de magnitude assinada. Em outras palavras, um inteiro de 8 bits não é um bit de sinal seguido por um inteiro não assinado de 7 bits. 

Em vez disso, números inteiros negativos são representados em um sistema chamado complemento de dois, o que permite um processamento aritmético mais fácil no hardware e também elimina a ambigüidade potencial de ter zero positivo e zero negativo. Um efeito colateral da eliminação do zero negativo é que há sempre um número negativo adicional disponível na parte inferior do intervalo. 

Outra propriedade interessante dos sistemas de complemento de dois é que o primeiro bit efetivamente funciona como um indicador de sinal (ou seja, todos os números iniciados com o bit 1 são negativos), mas os próximos sete bits não devem ser interpretados sozinhos um número não assinado ao qual o bit de sinal é aplicado.

O complemento de dois não é terrivelmente complicado, mas ter uma boa noção inicial do que é o complemento de dois e como e por que ele funciona provavelmente está além do escopo de uma resposta SO. Comece com o artigo da Wikipedia ou use o termo no Google para obter mais recursos.

Para tentar abordar brevemente sua consulta sobre -128, a idéia fundamental por trás da geração de um número de complemento de dois é pegar a forma não assinada do número, inverter todos os bits e adicionar um. Portanto, unsigned 128 é 10000000. Invertido, é 01111111, e adicionar um obtém 10000000 novamente. Portanto, em um sistema de complemento de dois, 10000000 é inequivocamente -128 e não +128. Números maiores ou iguais a +128 simplesmente não podem ser representados em 8 bits usando um sistema de complemento de dois porque seriam ambíguos com as formas de números negativos.

74
Tyler McHenry

O complemento de dois funciona da seguinte maneira;

Um byte consiste em 8 bits.

00000000 significa 0

11111111 significa 255

No entanto, se os números fossem apresentados assim, não poderíamos diferenciar se o número é positivo ou negativo. Por esse motivo, o bit do lado esquerdo nos dá essa informação. Se o bit no lado esquerdo for 0, você pode começar a adicionar o valor de outros bits no topo de zero. Se o bit for 1, você deve começar a adicionar no topo do -128. Porque o bit do lado esquerdo é dois para o poder de sete.

Exemplos;

Nestes exemplos, o bit no lado esquerdo é 1, isso significa que estamos adicionando os valores de outros bits no topo de -128.

10000000 = -128 (-128 + 0)

10000001 = -127 (-128 + 1)

10000011 = -125 (-128 + 3)

10000111 = -121 (-128 + 7)

Os mesmos bytes, mas desta vez, o bit à esquerda é 0. Isso significa que estamos começando a adicionar no topo do 0.

00000000 = 0 (0 + 0)

00000001 = 1 (0 + 1)

00000011 = 3 (0 + 3)

00000111 = 7 (0 + 7)

Se estamos bem até agora, a resposta para a sua pergunta, o menor número possível com 8 bits com esta regra é;

10000000 = -128

o maior número possível

011111111 = 127

É por isso que o intervalo está entre -128 e 127 .

14
Ad Infinitum

Como James apontou em seu comentário, é porque é assim que funciona o complemento de dois.

Se colocarmos em outros termos, você pode representar 2 ^ 8 = 256 tipos de valores. que é, neste caso, usado como 128 números negativos, 127 números positivos e zero. Se usássemos 7 bits para representar o valor, um bit para um sinal, poderíamos representar um valor a menos e também teríamos dois zeros (o que seria muito lamentável, pois comparar dois valores seria mais complicado por causa disso).

8
Tamás Szelei

Tipos numéricos básicos podem representar 2 ^ n números. Veja um caso n = 2. Você pode representar quatro casos, vamos chamá-los de a, b, c, d. Então você pode concordar com a=-2, b=-1, c=0, d=1 (isto é aceito) ou a=-1, b=0, c=1, d=2 (Possible, mas não usado). Portanto, se você tiver apenas um zero e manter 2 ^ n, seu abs(min) != max será aumentado. Aumentar o n move as bordas, mas abs(min) != max ainda é válido.

3
Sic

byte consiste em 8 bits ---> sinal de 1 bit (positivo ou negativo) valor de 7 bits 

então o intervalo -2 ^ 7 negativo (-128) a 2 ^ 7 -1 positivo (127)

1
Mina Fawzy

em Java todas as variáveis ​​como byte curto int longo float double são escritas como assinadas. então é muito simples o head head sempre especifica o que é (negativo ou positivo), mas porque os números são divisíveis por 2 half é deslocado como negativo, 0 é positivo por padrão. então parece com isso:

isso é positivo
+ | 0001001
1 | 0001001
isso é negativo
- | 0001001
0 | 0001001
como um byte curto um negativo é
- 000000011111111
0000000011111111

1
Andrei Bazavan

depois de pegar o complemento de dois nós sempre partimos com um estado representando o número extra, então transformamos esse estado em -128.

0
Rashid Ali

Sem entrar no complemento de dois: 2 ^ 8 (já que um byte tem 8 dígitos e pode ter 1 de 2 valores) = 256, então os valores mais individuais que um byte pode representar são 256. , representando os números -128 a -1 é metade do nosso intervalo. Acredito que a questão aqui é por que é o valor máximo positivo 127 em vez de 128. Isso ocorre porque temos que representar o número 0, então, inclusive, 0-127 são as outras 128 possibilidades do nosso intervalo.

Se estivéssemos apenas permitindo valores positivos, como um byte não assinado em que números negativos não são possíveis, o intervalo seria de 0 a 255, já que esses são 256 valores diferentes (incluindo 0).

0
David Hollowell - MSFT