Вопрос-ответ

Can we make unsigned byte in Java

Можем ли мы создать байт без знака в Java

Я пытаюсь преобразовать байт со знаком в байт без знака. Проблема в том, что данные, которые я получаю, без знака, а Java не поддерживает байт без знака, поэтому, когда он считывает данные, он обрабатывает их как подписанные.

Я попробовал преобразовать его с помощью следующего решения, которое я получил от Stack Overflow.

public static int unsignedToBytes(byte a)
{
int b = a & 0xFF;
return b;
}

Но когда он снова преобразуется в байт, я получаю те же подписанные данные. Я пытаюсь использовать эти данные в качестве параметра функции Java, которая принимает в качестве параметра только байт, поэтому я не могу использовать какой-либо другой тип данных. Как я могу исправить эту проблему?

Переведено автоматически
Ответ 1

Тот факт, что примитивы подписаны в Java, не имеет отношения к тому, как они представлены в памяти / передаче - байт состоит всего из 8 бит, и интерпретируете ли вы это как диапазон со знаком или нет, зависит от вас. Нет волшебного флага, чтобы сказать "это подписано" или "это без знака".

Поскольку примитивы подписаны, компилятор Java не позволит вам присваивать байту значение выше +127 (или меньше -128). Однако ничто не мешает вам понизить значение int (или short) для достижения этой цели:

int i = 200; // 0000 0000 0000 0000 0000 0000 1100 1000 (200)
byte b = (byte) 200; // 1100 1000 (-56 by Java specification, 200 by convention)

/*
* Will print a negative int -56 because upcasting byte to int does
* so called "sign extension" which yields those bits:
* 1111 1111 1111 1111 1111 1111 1100 1000 (-56)
*
* But you could still choose to interpret this as +200.
*/

System.out.println(b); // "-56"

/*
* Will print a positive int 200 because bitwise AND with 0xFF will
* zero all the 24 most significant bits that:
* a) were added during upcasting to int which took place silently
* just before evaluating the bitwise AND operator.
* So the `b & 0xFF` is equivalent with `((int) b) & 0xFF`.
* b) were set to 1s because of "sign extension" during the upcasting
*
* 1111 1111 1111 1111 1111 1111 1100 1000 (the int)
* &
* 0000 0000 0000 0000 0000 0000 1111 1111 (the 0xFF)
* =======================================
* 0000 0000 0000 0000 0000 0000 1100 1000 (200)
*/

System.out.println(b & 0xFF); // "200"

/*
* You would typically do this *within* the method that expected an
* unsigned byte and the advantage is you apply `0xFF` only once
* and than you use the `unsignedByte` variable in all your bitwise
* operations.
*
* You could use any integer type longer than `byte` for the `unsignedByte` variable,
* i.e. `short`, `int`, `long` and even `char`, but during bitwise operations
* it would get casted to `int` anyway.
*/

void printUnsignedByte(byte b) {
int unsignedByte = b & 0xFF;
System.out.println(unsignedByte); // "200"
}
Ответ 2

Я не уверен, что понимаю ваш вопрос.

Я только что попробовал это, и для байта -12 (значение со знаком) оно вернуло целое число 244 (эквивалентно значению байта без знака, но введено как int):

  public static int unsignedToBytes(byte b) {
return b & 0xFF;
}

public static void main(String[] args) {
System.out.println(unsignedToBytes((byte) -12));
}

Это то, что вы хотите сделать?

Java не позволяет выражать 244 как byte значение, как это было бы в C. Чтобы выразить положительные целые числа выше Byte.MAX_VALUE (127), вы должны использовать другой целочисленный тип, такой как short, int или long.

Ответ 3

Полное руководство по работе с неподписанными байтами в Java:

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

(Источник этого ответа.)


Язык Java не предоставляет ничего похожего на unsigned ключевое слово. A byte в соответствии со спецификацией языка представляет значение в диапазоне от -128 до 127. Например, если a byte преобразуется в int Java интерпретирует первый бит как знак и использует расширение знака.

При этом ничто не мешает вам просматривать byte просто как 8 бит и интерпретировать эти биты как значение от 0 до 255. Просто имейте в виду, что вы ничего не можете сделать, чтобы навязать свою интерпретацию чужому методу. Если метод принимает byte , то этот метод принимает значение от -128 до 127, если явно не указано иное.

Вот пара полезных преобразований / манипуляций для вашего удобства:

Преобразования в / из int

// From int to unsigned byte
int i = 200; // some value between 0 and 255
byte b = (byte) i; // 8 bits representing that value

// From unsigned byte to int
byte b = 123; // 8 bits representing a value between 0 and 255
int i = b & 0xFF; // an int representing the same value

(Или, если вы используете Java 8+, используйте Byte.toUnsignedInt.)

Синтаксический анализ / форматирование

Лучший способ - использовать приведенные выше преобразования:

// Parse an unsigned byte
byte b = (byte) Integer.parseInt("200");

// Print an unsigned byte
System.out.println("Value of my unsigned byte: " + (b & 0xFF));

Арифметика

Представление с двумя дополнениями "просто работает" для сложения, вычитания и умножения:

// two unsigned bytes
byte b1 = (byte) 200;
byte b2 = (byte) 15;

byte sum = (byte) (b1 + b2); // 215
byte diff = (byte) (b1 - b2); // 185
byte prod = (byte) (b2 * b2); // 225

Для разделения требуется ручное преобразование операндов:

byte ratio = (byte) ((b1 & 0xFF) / (b2 & 0xFF));
Ответ 4

В Java нет примитивных байтов без знака. Обычное дело - привести его к большему типу:

int anUnsignedByte = (int) aSignedByte & 0xff;
java