¿Por qué Java puede almacenar 0xff000000 como int?

El valor máximo de un entero en Java es 2147483647, ya que los enteros de Java están firmados, ¿verdad?

0xff000000 tiene un valor numérico de 4278190080.

Sin embargo, veo código Java así:

int ALPHA_MASK = 0xff000000; 

¿Alguien puede iluminarme por favor?

El bit alto es un bit de signo. Establecerlo denota un número negativo: -16777216.

Java, como la mayoría de los idiomas, almacena números firmados en forma de complemento a 2 . En este caso, al restar 2 31 , o 2147483648 de 0x7F000000, o 2130706432, se obtiene -16777216.

Solo una adición a la respuesta de Erickson:

Como dijo, los enteros con signo se almacenan como complementos de dos a su valor positivo respectivo en la mayoría de las architectures de computadoras.

Es decir, los 2 a 32 valores posibles se dividen en dos conjuntos: uno para valores positivos que comienzan con 0 bits y uno para valores negativos que comienzan con 1.

Ahora, imagine que estamos limitados a números de 3 bits. Vamos a organizarlos de una manera divertida que tendrá sentido en un segundo:

  000 111 001 110 010 101 011 100 

Verá que todos los números en el lado izquierdo comienzan con 1 bit mientras que en el lado derecho comienzan con 0. Con nuestra decisión anterior de declarar el primero como negativo y el último como positivo, vemos que 001 , 010 y 011 son los únicos números positivos posibles mientras que 111, 110 y 101 son sus respectivos contrapartes negativos.

Ahora, ¿qué hacemos con los dos números que están en la parte superior e inferior, respectivamente? 000 debe ser cero, obviamente, y 100 será el número negativo más bajo de todos, que no tiene una contraparte positiva. Para resumir:

  000 (0) 111 001 (-1 / 1) 110 010 (-2 / 2) 101 011 (-3 / 3) 100 (-4) 

Puede observar que puede obtener el patrón de bits de -1 (111) anulando 1 (001) y agregando 1 (001) a él: 001 (= 1) -> 110 + 001 -> 111 (= -1)

Volviendo a tu pregunta:

0xff000000 = 1111 1111 0000 0000 0000 0000 0000 0000

No es necesario que agreguemos ceros adicionales ya que ya alcanzamos el máximo de 32 bits. Además, obviamente es un número negativo (ya que está comenzando con 1 bit), así que ahora vamos a calcular su valor absoluto / homólogo positivo:

Esto significa que tomaremos el complemento de los dos

 1111 1111 0000 0000 0000 0000 0000 0000 

cual es

 0000 0000 1111 1111 1111 1111 1111 1111 

Luego agregamos

 0000 0000 0000 0000 0000 0000 0000 0001 

y obtener

 0000 0001 0000 0000 0000 0000 0000 0000 = 16777216 

Por lo tanto, 0xff000000 = -16777216.

Algo que probablemente vale la pena señalar: este código no debe usarse como un entero con un valor numérico; El propósito es como máscara de bits para filtrar el canal alfa de un valor de color de 32 bits. Esta variable realmente no debería considerarse como un número, solo como una máscara binaria con los 8 bits altos activados.

el bit adicional es para el signo

Los Java Ints son complemento a dos

Ints se firman en Java.