Я считаю, что вы видите здесь тот факт, что Java преобразует целые числа в длинные, используя расширение знака.
Для начала, что должен делать этот код?
int myInt = -1;
long myLong = myInt;
System.out.println(myLong);
Это должноинтуитивно распечатать -1, и это действительно так.Я имею в виду, было бы странно, если бы при преобразовании типа int в long мы не получили тот же номер, с которого начали.
Теперь давайте возьмем этот код:
int myInt = 0xFFFFFFFF;
long myLong = myInt;
System.out.println(myLong);
Что это печатает?Ну, 0xFFFFFFFF - это шестнадцатеричная версия подписанного 32-разрядного числа -1.Это означает, что этот код полностью эквивалентен приведенному выше коду, поэтому он должен (и должен) печатать одно и то же значение -1.
Но значение -1, закодированное как long, не имеет представления0x00000000FFFFFFFF.Это будет 2 32 - 1, а не -1.Скорее всего, поскольку он длиной 64 бита, -1 представляется как 0xFFFFFFFFFFFFFFFFF.К сожалению, все верхние биты только что активированы!Это делает его не очень эффективным в качестве битовой маски.
Правило в Java состоит в том, что если вы преобразуете int в long, если самый первый бит в int равен 1, то все 32 старших бита longбудет установлен в 1, а также.Это так, что преобразование целого числа в длинное сохраняет числовое значение.
Если вы хотите создать битовую маску длиной 64 бита, инициализируйте ее длинным литералом, а не литералом int:
mask = 0xFFFFFFFFL; // note the L
Почему это имеет значение?Без L Java обрабатывает код как
- Создает целочисленное значение 0xFFFFFFFF = -1, давая 32 бита.
- Преобразует это целочисленное значение в long.Для этого используйте расширение знака, чтобы преобразовать его в длинное значение -1, давая 64 бита подряд.
Однако, если вы включите L, Java интерпретирует такие вещи как:
- Создайте длинное значение 0xFFFFFFFF = 2 32 - 1, которое представляет собой 32 нулевых бита, за которыми следуют 32 однобитных.
- Присвойте это значение маске.
Надеюсь, это поможет!