Подтвердить что ты не робот

Беззнаковые байты в Java

Байты в Java подписаны по умолчанию. Я вижу на других сообщениях, что обходной путь для беззнаковых байтов аналогичен таковому: int num = (int) bite & 0xFF

Может кто-нибудь объяснить мне, почему это работает и преобразует подписанный байт в беззнаковый байт, а затем его соответствующее целое число? ANDing байт с 11111111 приводит к тому же байту - правильно?

4b9b3361

Ответ 1

Признак типа имеет более высокий приоритет, чем оператор &. Поэтому вы сначала бросаете int, а затем ANDing, чтобы замаскировать все установленные старшие биты, включая "знаковый бит" из двух дополнений, которые использует java, оставляя вам только положительное значение исходный байт. Например:.

let byte x = 11111111 = -1
then (int) x = 11111111 11111111 11111111 11111111
and x & 0xFF = 00000000 00000000 00000000 11111111 = 255

и вы эффективно удалили знак из исходного байта.

Ответ 2

Инициализация байта с 11111111 приводит к тому же байту - правильно?

За исключением AND AND с 00000000000000000000000011111111, потому что 0xFF является литералом int - в Java нет литералов byte. Итак, что происходит, это то, что byte продвигается до int (тип не нужен), имеет расширенный знак (т.е. Сохраняет возможное отрицательное значение byte), но затем расширение знака отменяется с помощью ANDing with with все эти нули. Результатом является int, который имеет как наименее значащие биты в точности предыдущий byte, и, следовательно, значение byte было бы без знака.

Ответ 3

В Java 8 такой метод появился в классе Byte:

/**
 * Converts the argument to an {@code int} by an unsigned
 * conversion.  In an unsigned conversion to an {@code int}, the
 * high-order 24 bits of the {@code int} are zero and the
 * low-order 8 bits are equal to the bits of the {@code byte} argument.
 *
 * Consequently, zero and positive {@code byte} values are mapped
 * to a numerically equal {@code int} value and negative {@code
 * byte} values are mapped to an {@code int} value equal to the
 * input plus 2<sup>8</sup>.
 *
 * @param  x the value to convert to an unsigned {@code int}
 * @return the argument converted to {@code int} by an unsigned
 *         conversion
 * @since 1.8
 */
public static int toUnsignedInt(byte x) {
    return ((int) x) & 0xff;
}

Ответ 4

Как вы видите, результат int не байт

Как это работает, скажем, у нас есть byte b = -128;, это представлено как 1000 0000, так что происходит, когда вы выполняете свою линию? Позвольте использовать temp int для этого, скажем:
int i1 = (int)b; i1 теперь -128, и это фактически представлено в двоичном виде следующим образом:

1111 1111 1111 1111 1111 1111 1000 0000

Итак, как выглядит i1 & 0xFF в двоичном формате?

1111 1111 1111 1111 1111 1111 1000 0000
&
0000 0000 0000 0000 0000 0000 1111 1111

что приводит к

0000 0000 0000 0000 0000 0000 1000 0000

и это ровно 128, то есть ваше подписанное значение преобразуется в unsigned.

Edit
Конвертированный байт -128 .. 127 в 0 .. 255

int unsignedByte = 128 + yourByte;

Вы не можете представлять значения с 128 по 255 с помощью байта, вы должны использовать что-то еще, например, int или smallint.

Ответ 5

Да, но таким образом вы можете быть уверены, что никогда не получите число > 255 или < 0.

Если первый бит равен 1, число отрицательно. Если вы конвертируете байт в int, если он отрицательный, он будет предварительно забит 1 байт, а если положительный - с 0 байтами. Запуск и процедура сбросят все байты слева от первого 8. Это фактически добавит 256 к отрицательным байтам.