Cálculo del rango de los números primitivos en Java

Hola a todos,

Al leer un tema referente al cálculo de los rangos de los números primitivos me he quedado atorado, ya que no logro entender exactamente cómo salen los cálculos. Por ejemplo:

Se dice que un byte tiene 8 bits, y que el rango de valores mas bajo es -2⁷ y el rango máximo de valores es 2⁷ - 1. Esto quiere decir que el rango mínimo que puede tener un byte es de -128 y el rango máximo es de 127. ¿Por qué?. Dice también que la formula para calcular estos valores es la siguiente:

Rango mínimo = -2^(bits-1)
Rango máximo = 2^(bits-1) - 1

Dando por hecho lo anterior, pues resulta fácil creer por dogma de fe en las fórmulas, pero si lo pasamos a binario, realmente no me queda muy claro.

Rango mínimo = 1-1-1-1-1-1-1-1 = -2⁷ = -128 (Ya que el bit mas a la izquierda indica que es de signo negativo)
Rango máximo = 0-1-1-1-1-1-1-1 = 2⁷ = 128

Se dice que el 0 se incluye entre los positivos y por eso es 127, pero entonces que sucede con la siguiente cantidad 0-1-1-1-1-1-1-1 = 128? ¿Entonces que sucede aquí? ¿Qué sucede con 0-0-0-0-0-0-0-0 = 0 y con 1-0-0-0-0-0-0-0 = -0?

En fin, estoy confundido, espero puedan ayudarme.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de mathemathician

Teoria del conteo

Las fórmulas se obtienen con teoría del conteo. Esta teoría comienza con el principio de la multiplicación que dice: "Si tú puedes hacer una actividad de n maneras y si otra actividad se realiza de m maneras entonces hay nX m formas de hacer ambas acitivdades juntas". Por ejemplo si tienes 3 pantalones y 4 camisas, entonces te puedes vestir de 12 formas diferentes. Este principio de la multiplicación es el que se está aplicando para obtener las fórmulas que dices. La justificación es más o menos como la siguiente.

Un bit se puede llenar de dos formas entonces con 8 bits se pueden formar 2x2x2x2x2x2x2x2=256 permutaciones diferentes. La mitad se usan para números negativos y la otra mitad menos 1 para números positivos. Se resta un 1 pues hay que considerar al cero.
La mitad de 256 es 128 por eso el valor mínimo es -128.
El valor máximo es 128-1

Es mejor ver el caso de 4 bits:
Con 4 bits los números se guardarian asi:

0111 7
0110 6
0101 5
0100 4
0011 3
0010 2
0001 1
0000 0
1111 −1
1110 −2
1101 −3
1100 −4
1011 −5
1010 −6
1001 −7
1000 −8

Con 4 bits se tienen 2x2x2x2=16 casos.La mitad es 2^3 . La mitad se usa para negativos y la mitad menos 1 se usa para positivos.
Observa que el 7 por ejemplo se guarda con su representacion binaria, mientras que -7 se guarda con su representación en complemento a 2. Usar el complemento a 2 simplifica el diseño de los circuitos lógicos para realizar operaciones como suma o resta.

Disculpa si no es clara la explicación. Pero es algo difícil comunicar un concepto matemático a través del mensajero. Tu problema lo puedes resolver estudiando un poco más teoría del conteo y complementos a 2.

Saludos.

Imagen de ezamudio

-0

Esto no es exclusivo de Java, pasa así con cualquier entero con signo. 01111111 es 127. 11111111 es -127. 00000000 es 128. El bit más significativo se usa para el signo. Por lo tanto, sí 10000000 es -0 pero como eso no tiene sentido, se usa como -128.

CORRECCION: 00000000 es 0, 01111111 es 127, 10000000 es -128 (porque -0 no tiene sentido), y 11111111 es -127 (o tal vez 11111111 es -1, por aquello del complemento a 2 pero son detalles de implementación a fin de cuentas).

Imagen de cfpmx

Hola mathemathician, Gracias

Hola mathemathician,

Gracias tomarte un momento para realizar tu explicación, y si te he entendido ya que no tengo tan malas bases matemáticas, jaja. También me ayudó a darme cuenta sobre la fórmula 2^n y sus respectivos ajustes 2^(bits-1) y 2^(bits-1) -1, que me traían algo confundido a la hora de hallar los valores, sin embargo, aunque tu respuesta siento que me ha ayudado a entender algunas cosas, mi duda se aproxima más a lo que ezamudio respondió (Que por cierto, creo que por ahí va, aunque me da la impresión que cometió un error por que el rango máximo de un byte es 127), es decir, tomando como base un número de 8 bits, en Java (o en cualquier otro lenguaje como menciona ezamudio) y sabiendo que su rango mínimo es -128 y su rango máximo es 127 entonces, que sucede con 1-1-1-1-1-1-1, 1-0-0-0-0-0-0, 0-0-0-0-0-0-0 ya que:

1-1-1-1-1-1-1 = -127
1-0-0-0-0-0-0 (Supongo tal vez que esta cantidad en Java es representada como -128 tomando como referencia la explicación de ezamudio)
0-0-0-0-0-0-0 = 0
0-1-1-1-1-1-1 = 127

Realmente, basándome en la explicación de ezamudio, creo así quedarían las cosas. Mi duda realmente era como Java representaba el -128, y qué pasaba con 0-0-0-0-0-0-0 y 1-0-0-0-0-0-0, teniendo únicamente 7 bits ya que el el octavo es para indicar el signo. Espero haberme explicado bien. ¡Hasta pronto y gracias!.

Atentamente cfpmx