Почему Java может хранить 0xff000000 как int?
Вопрос
Максимальное значение целого числа в Java - 2147483647, поскольку целые числа Java подписаны, верно?
0xff000000 имеет числовое значение 4278190080.
Тем не менее, я вижу код Java следующим образом:
int ALPHA_MASK = 0xff000000;
Может кто-нибудь просветить меня, пожалуйста?
Решение
Старший бит является знаковым битом. Установка означает отрицательное число: -16777216. Р>
Java, как и большинство языков, хранит числа со знаком в дополнении 2 . В этом случае вычитание 2 31 или 2147483648 из 0x7F000000 или 2130706432 дает -16777216.
Другие советы
Просто дополнение к ответу Эриксона:
По его словам, целые числа со знаком хранятся как два дополнения к их соответствующему положительному значению на большинстве компьютерных архитектур.
То есть все 2 ^ 32 возможных значения разбиты на два набора: один для положительных значений, начинающихся с 0-битного, и один для отрицательных значений, начинающихся с 1.
Теперь представьте, что мы ограничены 3-битными числами. Давайте устроим их забавным способом, который будет иметь смысл через секунду:
000
111 001
110 010
101 011
100
Вы видите, что все числа с левой стороны начинаются с 1-битного значения, тогда как с правой стороны они начинаются с 0. По нашему ранее принятому решению объявить первое как отрицательное, а второе как положительное, мы см., что 001, 010 и 011 являются единственно возможными положительными числами, тогда как 111, 110 и 101 являются их соответствующими отрицательными аналогами.
Теперь, что мы будем делать с двумя числами сверху и снизу соответственно? Очевидно, 000 должен быть равен нулю, а 100 будет самым низким отрицательным числом из всех, у которых нет положительного аналога. Подводя итог:
000 (0)
111 001 (-1 / 1)
110 010 (-2 / 2)
101 011 (-3 / 3)
100 (-4)
Вы можете заметить, что вы можете получить битовую комбинацию -1 (111), отрицая 1 (001) и добавляя к ней 1 (001): 001 (= 1) - > 110 + 001 - > 111 (= -1)
Возвращаясь к вашему вопросу:
0xff000000 = 1111 1111 0000 0000 0000 0000 0000 0000
Нам не нужно добавлять дополнительные нули перед ним, поскольку мы уже достигли максимума в 32 бита. Кроме того, это, очевидно, отрицательное число (так как оно начинается с 1-битного), поэтому мы сейчас рассчитаем его абсолютное значение / положительный аналог:
Это означает, что мы возьмем дополнение к двум
1111 1111 0000 0000 0000 0000 0000 0000
который
0000 0000 1111 1111 1111 1111 1111 1111
Затем мы добавляем
0000 0000 0000 0000 0000 0000 0000 0001
и получить
0000 0001 0000 0000 0000 0000 0000 0000 = 16777216
Следовательно, 0xff000000 = -16777216.
Что-то, вероятно, стоит отметить - этот код не предназначен для использования в качестве целого числа с числовым значением; Цель состоит в том, чтобы использовать битовую маску для фильтрации альфа-канала из 32-битного значения цвета. Эта переменная даже не должна восприниматься как число, просто как двоичная маска с включенными старшими 8 битами.
дополнительный бит для знака
Java-интты являются дополнением к двум
целые числа подписаны в Java.