Я читал книгу Сокеты TCP/IP в Java, 2nd Edition. Я надеялся получить больше ясности в чем-то, но, поскольку на веб-сайте книги нет форума или чего-то еще, я думал, что попрошу здесь. В нескольких местах книга использует маску байта, чтобы избежать расширения знака. Вот пример:Предотвращение расширения знака с помощью байтной маски
private final static int BYTEMASK = 0xFF; //8 bits
public static long decodeIntBigEndian(byte[] val, int offset, int size) {
long rtn = 0;
for(int i = 0; i < size; i++) {
rtn = (rtn << Byte.SIZE) | ((long) val[offset + i] & BYTEMASK);
}
return rtn;
}
Итак, вот моя догадка о том, что происходит. Дай мне знать, если я прав. BYTEMASK
в двоичном виде должно выглядеть как 00000000 00000000 00000000 11111111
. Чтобы упростить задачу, давайте просто скажем, что байт-байт val
содержит только 1 короткий, поэтому смещение равно 0. Поэтому давайте установим массив байтов в val[0] = 11111111
, val[1] = 00001111
. На i = 0
, rtn
все 0, поэтому rtn << Byte.SIZE
просто сохраняет значение одинаково. Тогда есть (long)val[0]
, что делает его 8 байтами со всеми 1 из-за расширения знака. Но когда вы используете & BYTEMASK
, он устанавливает все лишние 1 в 0, оставляя последний байт всех 1. Затем вы получаете rtn | val[0]
, который в основном переворачивает все 1 в последнем байте rtn
. Для i = 1
, (rtn << Byte.SIZE)
выталкивает младший байт и оставляет все 0 на месте. Затем (long)val[1]
делает длинный со всеми нулями плюс 00001111
для наименее значимого байта, который мы хотим. Поэтому использование & BYTEMASK
не меняет его. Затем, когда используется rtn | val[1]
, он переворачивает младший байт rtn
на все 1. Конечное значение возврата теперь составляет rtn = 00000000 00000000 00000000 00000000 00000000 00000000 11111111 11111111
. Итак, я надеюсь, что это было не слишком долго, и это было понятно. Я просто хочу знать, правильно ли я думаю об этом, а не просто полностью нарушил логику. Кроме того, меня смущает одна вещь: BYTEMASK
- 0xFF
. В двоичном коде это будет 11111111 11111111
, поэтому, если он неявно передается в int, не будет ли это на самом деле 11111111 11111111 11111111 11111111
из-за расширения знака? Если это так, то для меня не имеет смысла, как бы работать BYTEMASK
. Спасибо за чтение.
'0xFF' - это int, почему он должен быть расширен? А в двоичном виде это будет '11111111'. –
С первого взгляда этот пост выглядит странно похожим на позорный пост «XHTML с регулярным выражением» ... – Tharwen
Пони он приходит. –