Я пытаюсь преобразовать подписанный байт в неподписанный. Проблема в том, что данные, которые я получаю, не подписаны, а Java не поддерживает неподписанный байт, поэтому, когда он читает данные, он обрабатывает их как подписанные.
Я попытался преобразовать его с помощью следующего решения, полученного из Stack Overflow.
public static int unsignedToBytes(byte a)
{
int b = a & 0xFF;
return b;
}
Но когда он снова преобразуется в байты, я получаю те же подписанные данные. Я пытаюсь использовать эти данные в качестве параметра функции Java, которая принимает только байт в качестве параметра, поэтому я не могу использовать любой другой тип данных. Как я могу решить эту проблему?
Ответы:
Я не уверен, что понимаю ваш вопрос.
Я только что попробовал это и для байта -12 (значение со знаком) он возвратил целое число 244 (эквивалентно значению байта без знака, но напечатано как
int
):Это то, что вы хотите сделать?
Java не позволяет выражать 244 как
byte
значение, как и C. Чтобы выразить положительные целые числа вышеByte.MAX_VALUE
(127), вы должны использовать другой целочисленный тип, напримерshort
,int
илиlong
.источник
byte b = (byte)unsignedToBytes((byte) -12);
Теперь попробуйте распечатать бТот факт, что примитивы подписаны в Java, не имеет отношения к тому, как они представлены в памяти / транзите - байт составляет всего 8 бит, и независимо от того, интерпретируете ли вы его как диапазон со знаком или нет, зависит от вас. Там нет волшебного флага, чтобы сказать «это подписано» или «это не подписано».
Поскольку примитивы подписаны, компилятор Java не позволит вам присвоить байту значение больше +127 (или меньше -128). Тем не менее, нет ничего, что могло бы помешать вам уменьшить int (или short) для достижения этой цели:
источник
Полное руководство по работе с неподписанными байтами в Java:
Байт без знака в Java
(Источник для этого ответа.)
Язык Java не предоставляет ничего похожего на
unsigned
ключевое слово. Abyte
согласно спецификации языка представляет значение в диапазоне от -128 до 127. Например, если abyte
приведен кint
Java, он будет интерпретировать первый бит как знак и использовать расширение знака .При этом ничто не мешает вам рассматривать
byte
просто как 8 бит и интерпретировать эти биты как значение между 0 и 255. Просто имейте в виду, что вы ничего не можете сделать, чтобы навязать свою интерпретацию чужому методу. Если метод принимает abyte
, то этот метод принимает значение в диапазоне от -128 до 127, если явно не указано иное.Вот пара полезных преобразований / манипуляций для вашего удобства:
Преобразования в / из int
(Или, если вы используете Java 8+, используйте
Byte.toUnsignedInt
.)Разбор / форматирование
Лучший способ - использовать приведенные выше преобразования:
Арифметика
Представление из 2-х «просто работает» для сложения, вычитания и умножения:
Деление требует ручного преобразования операндов:
источник
В Java нет примитивных байтов без знака. Обычная вещь, чтобы привести его к большему типу:
источник
Я думаю, что другие ответы касались представления памяти, и то, как вы справитесь с этим, зависит от контекста того, как вы планируете его использовать. Я добавлю, что в Java 8 добавлена поддержка работы с неподписанными типами . В этом случае вы можете использовать
Byte.toUnsignedInt
источник
Примечание: если вы хотите распечатать, вы можете просто сказать
источник
println(b & 0xff)
достаточноЕсли вы думаете, что ищете что-то подобное.
источник
Адамский предоставил лучший ответ, но он не совсем полный, поэтому прочитайте его ответ, так как он объясняет детали, которыми я не являюсь.
Если у вас есть системная функция, которая требует, чтобы ей был передан неподписанный байт, вы можете передать подписанный байт, поскольку он автоматически будет обрабатывать его как неподписанный байт.
Таким образом, если системной функции требуются четыре байта, например, 192 168 0 1 как байты без знака, вы можете передать -64 -88 0 1, и функция все равно будет работать, потому что процесс передачи их функции отменяет их подпись. ,
Однако вряд ли у вас возникнет эта проблема, так как системные функции скрыты за классами для кроссплатформенной совместимости, хотя некоторые из методов чтения java.io возвращают невыгруженные байты в виде целых чисел.
Если вы хотите, чтобы это работало, попробуйте записать подписанные байты в файл и прочитать их обратно как неподписанные байты.
источник
Вы также можете:
Объяснение:
скажем
a = (byte) 133;
В памяти он хранится как: «1000 0101» (0x85 в шестнадцатеричном формате)
Таким образом , ее представление переводит без знака = 133, подписанный = -123 (как дополнение до 2)
Когда сдвиг влево выполняется на 24 бита влево, результатом является 4-байтовое целое число, которое представляется в виде:
«10000101 00000000 00000000 00000000» (или «0x85000000» в шестнадцатеричном формате)
тогда мы имеем
и он снова сдвигается на правильные 24 бита, но заполняется ведущими нулями. Так что это приводит к:
«00000000 00000000 00000000 10000101» (или «0x00000085» в шестнадцатеричном формате)
и это представление без знака, равное 133.
Если вы попытались выполнить приведение,
a = (int) a;
то получится, что он сохранит представление байта в дополнении 2 и сохранит его как int, а также дополнение 2:(int) "10000101" ---> "11111111 11111111 11111111 10000101"
И это переводится как: -123
источник
java.lang.Byte.toUnsignedInt(byte value)
. И если вы еще не используете Java 8, обновите как можно скорее. Java 7 и более ранние версии являются окончательными.Это существенно не отличается от функции, принимающей целое число, которому вы хотите передать значение больше 2 ^ 32-1.
Похоже, это зависит от того, как функция определена и задокументирована; Я вижу три возможности:
Это может явно задокументировать, что функция обрабатывает байт как значение без знака, и в этом случае функция, вероятно, должна делать то, что вы ожидаете, но, похоже, будет реализована неправильно. Для целочисленного случая функция, вероятно, объявила бы параметр как целое число без знака, но это невозможно для байтового случая.
Он может задокументировать, что значение этого аргумента должно быть больше (или, возможно, равно) нулю, и в этом случае вы неправильно используете функцию (передавая параметр вне диапазона), ожидая, что она сделает больше, чем было задумано делать. При некотором уровне поддержки отладки вы можете ожидать, что функция сгенерирует исключение или не выполнит утверждение.
Документация может ничего не говорить, в этом случае отрицательный параметр, ну, в общем, отрицательный параметр, и имеет ли это какое-либо значение, зависит от того, что делает функция. Если это бессмысленно, то, возможно, функция должна быть действительно определена / задокументирована как (2). Если это имеет смысл неочевидным образом (например, неотрицательные значения используются для индексации в массиве, а отрицательные значения используются для индексации назад от конца массива, так что -1 означает последний элемент), документация должна сказать, что это значит, и я ожидаю, что это не то, что вы хотите, чтобы все равно делать.
источник
Если у вас есть функция, которой необходимо передать подписанный байт, что вы ожидаете от нее, если вы передадите неподписанный байт?
Почему вы не можете использовать любой другой тип данных?
Необычно вы можете использовать байт как неподписанный байт с простым переводом или без него. Все зависит от того, как оно используется. Вам нужно будет уточнить, что вы собираетесь делать с ним.
источник
Хотя может показаться раздражающим (исходя из C), что Java не включил в язык неподписанный байт, на самом деле это не составляет большого труда, поскольку простая операция "b & 0xFF" возвращает значение без знака для (подписанного) байта b в (редком) ситуации, в которых это действительно необходимо. Биты на самом деле не меняются - только интерпретация (что важно только при выполнении, например, некоторых математических операций со значениями).
источник
x & 0xFF
везде, где вам это нужно, либо повторяете что-то, какbehaveLikeAnUnsignedByte(x)
везде. Это необходимо для каждого отдельного места, где вы используете байтовое значение или байтовый массив, который должен быть без знака, не существует мыслимого способа избежать этого повторения. Вы не можете написать реализацию протокола, который читает и записывает байтовые значения только с одной ссылкой на байтовую переменную. Ваш упрощенный взгляд может объяснить, почему они никогда не заботились об этом.В Java нет неподписанного байта, но если вы хотите отобразить байт, вы можете сделать,
Вывод:
Для получения дополнительной информации, пожалуйста, проверьте, Как отобразить шестнадцатеричное / байтовое значение в Java .
источник
java.lang.Byte.toUnsignedInt(byte value);
существует для этого.Согласно ограничениям в Java, беззнаковый байт почти невозможен в текущем формате типа данных. Вы можете обратиться к некоторым другим библиотекам другого языка для того, что вы реализуете, а затем вы можете вызывать их с помощью JNI .
источник
Да и нет. Я копался с этой проблемой. Как я понимаю это:
Дело в том, что Java имеет подписанное число от -128 до 127. Можно представить неподписанное в Java с помощью:
Например, если вы добавляете число со знаком -12, чтобы оно было без знака, вы получаете 244. Но вы можете использовать этот номер снова в знаке, его нужно перевести обратно в число со знаком, и оно снова будет -12.
Если вы попытаетесь добавить 244 к байту Java, вы получите исключениеOfIndexException.
Ура ..
источник
java.lang.Byte.toUnsignedInt(byte value);
существует для этого.Если вам нужны байты без знака в Java, просто вычтите 256 из числа, которое вас интересует. Это даст два дополнения. с отрицательным значением, которое является желаемым числом в байтах без знака.
Пример:
Вы должны использовать такие грязные хаки, когда используете leJOS для программирования кирпича NXT .
источник
speed_unsigned
подписано. Распечатай и посмотри. (И- 256
здесь ничего не получается.)