2010-09-01 23 views
56

No entiendo por qué el valor más bajo que puede tomar un byte es -128. Puedo ver que el valor más alto es 127, porque es 01111111 en binario, pero ¿cómo representa uno -128 con solo 8 bits, uno de los cuales se utiliza para el signo? El 128 positivo ya sería de 8 bits, es decir, 10000000, y luego necesitaría un noveno bit para representar el signo negativo.¿Por qué el rango de bytes -128 a 127 en Java?

¿Podría alguien por favor ayuda a explicarme esto?

+19

[complemento a dos] (http: //en.wikipedia.org/wiki/Two's_complement) –

+1

Es similar para los otros tipos enteros 'short',' int' y 'long'. – starblue

+6

Una mejor pregunta es '¿por qué el tipo de byte de Java no es un rango de 0..255'? De hecho, muchos hacen esta pregunta, en la mayoría de los idiomas el tipo byte no está firmado, pero en java 'byte' también está firmado, y yo (y muchos otros) creo que fue un mal diseño que permaneció en Java desde el primer día. Hay problemas cuando trabajas JNI, y créanme cuando nombras algo 'byte' que quieres 0..255! –

Respuesta

63

La respuesta es two's complement.

En resumen, Java (y la mayoría de los idiomas modernos) no representan enteros con signo que utilizan la representación de magnitud con signo. En otras palabras, un entero de 8 bits no es un bit de signo seguido de un entero sin signo de 7 bits.

En cambio, los enteros negativos se representan en un sistema llamado complemento de dos, que permite un procesamiento aritmético más sencillo en el hardware, y también elimina la posible ambigüedad de tener cero positivo y cero negativo. Un efecto secundario de eliminar el cero negativo es que siempre hay un número negativo adicional disponible en el extremo inferior del rango.

Otra propiedad interesante de de dos sistemas de complemento es que el primer bit hace efectivamente función como un indicador de señal (es decir, todos los números que empiezan con el bit 1 son negativos), pero los próximos siete bits no se han de interpretar en su propio como un número sin signo al que se aplica el bit de signo.

Complemento de dos no es terriblemente complicado, pero obtener un buen control inicial de qué complemento dos y cómo y por qué funciona es, probablemente, más allá del alcance de una respuesta SO. Comience con el artículo de Wikipedia o busque el término google para obtener más recursos.

Para intentar abordar brevemente su consulta sobre -128, la idea fundamental detrás de generar un número de complemento de dos es tomar la forma sin signo del número, invertir todos los bits y agregar uno. Entonces, el 128 sin signo es 10000000. Invertido, es 01111111, y al agregar uno se obtiene 10000000 nuevamente. Entonces, en un sistema de complemento de dos, 10000000 es inequívocamente -128 y no +128. Los números mayores o iguales a +128 simplemente no se pueden representar en 8 bits utilizando un sistema de complemento de dos porque serían ambiguos con las formas de los números negativos.

+0

¡Aseado! Veamos si lo entendí bien: sigue siendo cierto que los números de 8 bits que comienzan con 0 (distintos de 00000000) SON positivos, y comenzando con 1 ¿SON negativos? Además, la única cosa realmente complicada sobre el complemento de dos es que la representación de bits de los bytes no tiene el mismo valor que en una clase de matemática, es decir, 10000000 es normalmente +128, pero como byte es -128. Amirite? –

+0

Estás en lo correcto. El primer bit es 1 si y solo si el número es negativo. Si el primer bit es 0, el número es positivo o cero. –

+0

@Tyler: Apuesto a que podría responder a mi pregunta en virtud de este artículo, así: http://stackoverflow.com/questions/16775169/java-binary-literals-value-128-for-byte espero que esto es no muy directo hacia adelante, pero realmente me pregunto y después de unos meses de búsqueda esporádica todavía no tengo ni idea: ~ – JBA

8

Como señaló James en su comentario, es porque así es como funciona el complemento a dos.

Si lo expresamos en otros términos, puede representar 2^8 = 256 tipos de valores. que es, en este caso, usado como 128 números negativos, 127 números positivos y cero. Si usáramos 7 bits para representar el valor, +1 bit para un signo, podríamos representar un valor menor y también tendríamos dos ceros (lo cual sería muy desafortunado ya que la comparación de dos valores sería más complicada debido a eso).

1

en java todas las variables como byte short int long double float double se escriben como signed. por lo que es muy simple el bit de cabecera siempre especifica qué es (negativo o positivo), pero debido a que los números son divisibles por 2 mitad se desplaza como negativo, 0 es positivo por defecto. por lo que se parece a esto:

esto es positivo
+ | 0001001
1 | 0001001
esto es negativo
- | 0001001
0 | 0001001
como un byte corta un negativo es
-000000011111111

3

dad numérica básico pes puede representar 2^n números. Mira un caso n = 2. Puede representar cuatro casos, vamos a llamarlos a, b, c, d. Entonces puede aceptar a=-2, b=-1, c=0, d=1 (esto es aceptado) o a=-1, b=0, c=1, d=2 (Posible, pero no usado). Por lo tanto, si solo tiene un cero y mantiene 2^n indica que su abs(min) != max Al aumentar el n se mueven los bordes, pero abs(min) != max aún se mantiene.

1

byte consta de 8 bits --- signo> 1 bit (positivo o negativo) valor de 7 bits

lo que el rango -2^7 negativo (-128) a 2^7 -1 positivo (127)

0

Sin entrar en complemento a dos: 2^8 (puesto que un byte es de 8 dígitos y puede tener 1 de 2 valores) = 256, por lo que los valores más individuales un byte puede representar es 256. así, que representa los números -128 a -1 es la mitad de nuestro rango. Creo que la pregunta aquí es por qué el valor positivo máximo es 127 en lugar de 128. Esto se debe a que tenemos que representar el número 0, por lo que inclusive 0-127 son las otras 128 posibilidades de nuestro rango.

Si solo permitiéramos valores positivos, como un byte sin signo donde los números negativos no son posibles, el rango sería 0-255, ya que estos son 256 valores diferentes (incluido el 0).

6

Además de las respuestas aquí, puedo explicar cómo funcionan los dos complementos.

Un byte consta de 8 bits.

00000000 significa 0

11111111 significa 255

Sin embargo, si nos limitamos a decir así, no podemos diferenciar entre si el número es positivo o negativo. Por esta razón, el bit en el lado izquierdo nos da esta información. Si el bit en el lado izquierdo es 0, puede comenzar a agregar el valor de otros bits en la parte superior de cero. Si el bit es 1, deberías comenzar a agregar en la parte superior de -128. Porque el bit en el lado izquierdo es dos a la potencia de siete.

Ejemplos;

En estos ejemplos, el bit en el lado izquierdo es 1, significa que estamos agregando los valores de otros bits en la parte superior de -128.

10000000 = -128 (-128 + 0)

10000001 = -127 (-128 + 1)

10000011 = -125 (-128 + 3)

10000111 = -121 (-128 + 7)

mismas bytes, pero esta vez, el bit de la izquierda es 0. esto quiere decir, que estamos empezando a añadir en la parte superior de 0.

00000000 = 0 (0 + 0)

00000001 = 1 (0 + 1)

00000011 = 3 (0 + 3)

00000111 = 7 (0 + 7)

Si estamos bien hasta ahora, la respuesta a su pregunta, el número más pequeño posible con 8 bits con esta regla es;

10000000 = -128

el mayor número posible

011111111 = 127

Por eso, el rango es de entre -128 y 127.

Cuestiones relacionadas