Как преобразовать Int в байт без знака и обратно
мне нужно преобразовать число в байт без знака. Число всегда меньше или равно 255, и поэтому оно поместится в один байт.
мне нужно, чтобы преобразовать этот байт обратно в номер. Как бы я сделал это на Java? Я пробовал несколько способов, и ни один не работает. Вот что я пытаюсь сделать сейчас:
int size = 5;
// Convert size int to binary
String sizeStr = Integer.toString(size);
byte binaryByte = Byte.valueOf(sizeStr);
и теперь, чтобы преобразовать этот байт обратно в номер:
Byte test = new Byte(binaryByte);
int msgSize = test.intValue();
понятно, что это не работает. По какой-то причине, он всегда преобразует число в 65. Есть предложения?
8 ответов:
байт всегда подписан на Java. Вы можете получить его беззнаковое значение, двоичное-anding его с 0xFF, хотя:
int i = 234; byte b = (byte) i; System.out.println(b); // -22 int i2 = b & 0xFF; System.out.println(i2); // 234
Java 8 обеспечивает
Byte.toUnsignedIntпреобразованиеbytetointпутем преобразования без знака. В компании Oracle JDK для этого достаточно просто реализуется какreturn ((int) x) & 0xff;потому что HotSpot уже понимает, как оптимизировать этот шаблон, но он может быть интринсифицирован на других виртуальных машинах. Что еще более важно, никаких предварительных знаний не требуется, чтобы понять, что такое вызовtoUnsignedInt(foo)делает.в общей сложности, Java 8 предоставляет методы для преобразования
byteиshortв unsignedintиlong, иintв unsignedlong. Метод для преобразованияbyteв unsignedshortбыл умышленно опущено потому что JVM предоставляет только арифметику наintиlongв любом случае.чтобы преобразовать int обратно в байт, просто используйте cast:
(byte)someInt. В результате сужающееся примитивное преобразование отбросит все, кроме последних 8 бит.
Если вам просто нужно преобразовать ожидаемое 8-битное значение из подписанного int в беззнаковое значение, вы можете использовать простой сдвиг битов:
int signed = -119; // 11111111 11111111 11111111 10001001 /** * Use unsigned right shift operator to drop unset bits in positions 8-31 */ int psuedoUnsigned = (signed << 24) >>> 24; // 00000000 00000000 00000000 10001001 -> 137 base 10 /** * Convert back to signed by using the sign-extension properties of the right shift operator */ int backToSigned = (psuedoUnsigned << 24) >> 24; // back to original bit patternhttp://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
если используется что-то другое, чем
intкак базовый тип, Вам, очевидно, нужно будет настроить количество сдвига:http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.htmlкроме того, имейте в виду, что вы не можете использовать
byteвведите, это приведет к подписанному значению, как указано другими ответчиками. Самый маленький примитивный тип, который можно использовать для представления 8-разрядного значения без знака, будетshort.
The
Integer.toString(size)вызов преобразуется в представление char вашего целого числа, т. е. char'5'. Элемент представление ASCII этого символа является значение 65.вам нужно сначала разобрать строку до целого значения, например, используя
Integer.parseInt, чтобы вернуть исходное значение.в качестве итоговой строки для преобразования со знаком / без знака лучше всего оставить
Stringиз изображения и использовать бит манипуляции как @JB предлагает.
решение работает отлично (спасибо!), но если вы хотите избежать приведения и оставить работу низкого уровня в JDK, вы можете использовать DataOutputStream для записи ваших int и DataInputStream для их чтения. Они автоматически обрабатываются как беззнаковые байты, то:
для преобразования int в двоичные байты;
ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); int val = 250; dos.write(byteVal); ... dos.flush();читать их обратно в:
// important to use a (non-Unicode!) encoding like US_ASCII or ISO-8859-1, // i.e., one that uses one byte per character ByteArrayInputStream bis = new ByteArrayInputStream( bos.toString("ISO-8859-1").getBytes("ISO-8859-1")); DataInputStream dis = new DataInputStream(bis); int byteVal = dis.readUnsignedByte();Esp. полезно для обработки двоичных форматов данных (например, плоских форматов сообщений и т. д.)
обработка байтов и целых чисел без знака с помощью BigInteger:
byte[] b = ... // your integer in big-endian BigInteger ui = new BigInteger(b) // let BigInteger do the work int i = ui.intValue() // unsigned value assigned to i
Если вы хотите использовать примитивные классы-обертки, это будет работать, но все типы Java подписаны по умолчанию.
public static void main(String[] args) { Integer i=5; Byte b = Byte.valueOf(i+""); //converts i to String and calls Byte.valueOf() System.out.println(b); System.out.println(Integer.valueOf(b)); }
в java 7
public class Main { public static void main(String[] args) { byte b = -2; int i = 0 ; i = ( b & 0b1111_1111 ) ; System.err.println(i); } }результат : 254
Comments