побитовое-ANDing с 0xff важно?

не означает ли побитовое ANDing с 0xff по существу получение того же значения обратно, если на то пошло, в этом коде?

byte[] packet = reader.readPacket();
short sh;
sh = packet[1];
sh &= 0xFF;
System.out.print(sh+" ");

странно, я получаю -1, если этот ANDing не включен, но 255, когда включен, может ли кто-нибудь объяснить причину?

Как я вижу, 0xff-это просто 1111 1111. Не так ли?

3 ответов


да 0xff это просто 1111 1111. Но это попытка отобразить значение байта без знака, даже если в Java bytes подписаны. Значение 0xff is -1 за подписью byte, но это 255 на short.

когда byte стоимостью 0xff считывается, печать значения даст -1. Так это назначить short который имеет больший диапазон и может хранить byte значения, которые обычно переполняются, чтобы быть отрицательным числом как byte как положительное целое число, например, 144 как byte is 0x90, или -112, но его можно правильно хранить как 144 как short.

так byte стоимостью -1 назначена short. Но что это дает? Происходит примитивное расширяющееся преобразование, а отрицательные значения расширяются знаком. Так что 1111 1111 становится 11111111 11111111, еще -1, но на этот раз как short.

затем маски 0xff (00000000 11111111) используется для получения последних 8 бит опять:

  -1: 11111111 1111111
0xFF: 00000000 1111111
======================
 255: 00000000 1111111

это просто способ получить беззнаковое byte значение, преобразуя его в short а затем маскировка исходных бит из byte, чтобы отобразить его как беззнаковое значение.


A byte имеет диапазон от -128 до 127. Это означает, что некоторые значения отрицательны. Это все значения, где установлен верхний бит. Так что (byte) 0xFF - Это -1. Когда вы используете расширение знака, чтобы сделать его подписанным коротким, он становится (short) 0xFFFF что равно -1 как короткое. Когда вы маскируете его, он отрубает расширенные биты, и вы относитесь к байту, как если бы он был без знака.


вы не получаете -1, если ваш код не отличается от того, что у вас есть в вопрос.

for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) {
    short s = b;
    s &= 0xff;
    System.out.println(b + " & 0xFF = " + s);
}

печать

-128 & 0xFF = 128
-127 & 0xFF = 129
....
-2 & 0xFF = 254
-1 & 0xFF = 255
0 & 0xFF = 0
1 & 0xFF = 1
...
125 & 0xFF = 125
126 & 0xFF = 126

(предполагая, что два дополняют везде) две вещи:

  1. байты подписаны, так что 0xff в байте равно -1.
  2. при переходе от меньшего типа данных большее типа данных (в данном случае с byte до short), то стоимостью хранится. Итак,sh = packet[1] установить sh до -1, которая составляет 0xffff.

дело с пунктом #2 в том, что" дополнительные " биты дополняются 1s, чтобы сохранить значение всякий раз, когда исходное значение отрицательное. Идея Андинг с 0xff Это sh содержит 0x00ff, С этими" дополнительными " 1 теперь удалены.