如何将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
。 有什么build议么?
一个字节总是用Java签名。 虽然你可以用二进制来获得它的无符号值,
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
通过无符号转换将byte
转换为int
。 在Oracle的JDK中,这只是作为return ((int) x) & 0xff;
因为HotSpot已经理解如何优化这种模式,但是它可能是其他虚拟机的内在原因。 更重要的是,不需要事先知道来理解对toUnsignedInt(foo)
的调用。
总的来说,Java 8提供了将byte
和short
转换为unsigned int
和long
以及将int
为unsigned long
。 将byte
转换为unsigned short
被故意省略,因为JVM只提供int
和long
算术运算。
要将一个int转换回一个字节,只需使用一个(byte)someInt
: (byte)someInt
。 由此产生的窄化原始转换将丢弃除最后8位以外的所有数据。
如果您只需要将有符号整数的8位值转换为无符号值,则可以使用简单的位移:
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 pattern
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
如果使用除int
以外的其他东西作为基本types,则显然需要调整移位量: http : //docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
另外,请记住,您不能使用byte
types,这样做会导致其他答复者提到的有符号值。 你可以用来表示一个8位无符号值的最小的原始types是一个short
。
Integer.toString(size)
调用将转换为您的整数的char表示forms,即char'5 '5'
。 该字符的ASCII表示是值65。
您需要首先将stringparsing为一个整数值,例如通过使用Integer.parseInt
来获取原始的int值。
作为底线,对于有符号/无符号的转换,最好将String
留在图片之外,并像@JB所示的那样使用位操作。
该解决scheme工作正常(谢谢!),但如果您想要避免强制转换并将低级别工作保留给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, // ie, 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
如果你想使用原始的包装类,这将工作,但所有的Javatypes都默认签名。
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)); }