print - ¿Por qué el rango de bytes-128 a 127 en Java?
java print byte array (7)
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 9º bit para representar el signo negativo.
¿Podría alguien ayudarme a explicarme esto?
Como James señaló 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).
El complemento a dos funciona de la siguiente manera;
Un byte consta de 8 bits.
00000000 significa 0
11111111 significa 255
Sin embargo, si los números se presentan así, no podríamos 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 zero
. 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)
Los mismos bytes pero esta vez, el bit de la izquierda es 0
. Eso significa que estamos comenzando a agregar 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, es el número más pequeño posible con 8 bits con esta regla;
10000000 = -128
la mayor cantidad posible
011111111 = 127
Por eso, el rango está entre -128 y 127 .
La respuesta es complemento de dos .
En resumen, Java (y la mayoría de los lenguajes modernos) no representan enteros con signo que utilizan una representación de magnitud firmada. 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 los sistemas complementarios de dos es que el primer bit efectivamente funciona como un indicador de signo (es decir, todos los números que comienzan con el bit 1 son negativos), pero los siguientes siete bits no deben interpretarse por sí solos como un número sin signo para el cual se aplica el bit de signo.
El complemento de dos no es terriblemente complicado, pero obtener un buen control inicial sobre cuál es el complemento de dos y cómo y por qué funciona probablemente esté fuera del alcance de una respuesta de 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.
Los tipos numéricos básicos pueden 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 a=-2, b=-1, c=0, d=1
(esto es aceptado) o a=-1, b=0, c=1, d=2
(Posible, pero no utilizado). Por lo tanto, si solo tiene un cero y mantiene 2 ^ n declara sus abs(min) != max
Aumentando el n
mueven los bordes, pero abs(min) != max
aún se mantiene.
Sin entrar en el complemento a dos: 2 ^ 8 (ya que un byte es de 8 dígitos y puede tener 1 de 2 valores) = 256, entonces la mayoría de los valores individuales que un byte puede representar es 256. Entonces, representar 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 estuviéramos permitiendo 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).
el byte consiste en 8 bit ---> 1 bit sign (positivo o negativo) 7 bit value
entonces el rango -2 ^ 7 negativo (-128) a 2 ^ 7 -1 positivo (127)
en java todas las variables como byte short int long double float double se escriben como signed. por lo tanto, es muy simple que el bit de cabecera siempre especifique lo que es (negativo o positivo), pero dado que los números son divisibles por 2 medios se cambia como negativo, 0 es positivo por defecto. así que se ve así:
esto es positivo
+ | 0001001
1 | 0001001
esto es negativo
- | 0001001
0 | 0001001
como un byte corto un negativo es
-000000011111111
0000000011111111