在Java中, byte
是8位带符号(正和负)数据类型,其值从-128 (-2^7)
到127 (2^7-1)
。 对于unsigned byte
,允许的值是0
到255
。
Java没有无符号字节(0到255)。 要创建一个无符号字节,我们可以将该byte
转换为一个int
并使用0xff
屏蔽(按位和)新的int
以获取最后8位或防止符号扩展。
byte aByte = -1;
int number = aByte & 0xff; // bytes to unsigned byte in an integer.
为什么将字节转换为整数?
Java使用二进制补码来表示带符号的数字(正号和负号),最左边的位表示符号(0为正,1为负),其余位表示从-128 (-2^7)
到127 (2^7-1)
,所谓的8位byte
只有7位存储值。 多余的值(128 – 255)无法容纳在单个byte
,我们将其强制转换为32位无符号整数以获得更多空间(位)。
先决条件
1.字节到无符号字节
1.1查看下表,了解byte
到unsigned byte (int)
转换:
字节 | 无符号字节 |
---|---|
1个 | 1个 |
2 | 2 |
127 | 127 |
-128 | 128 |
-127 | 129 |
-126 | 130 |
-2 | 254 |
-1 | 255 |
1.2首先,我们将8位byte
转换为32位int
。
例如, byte -1
为二进制补码,二进制为1111 1111
。
# two's complement formula to convert positive to negative
# leftmost bit, 1 is negative, 0 is positive
0000 0001 (1)
1111 1110 (invert bits)
1111 1111 (add 1)
1111 1111 (-1)
当我们将一个byte
转换或转换为一个int
,它将把位从8增加到32。将使用符号扩展名并填写增加的位的值。
1111 1111 (-1)
byte -> int
???? ???? | ???? ???? | ???? ???? | 1111 1111
sign extension
1111 1111 | 1111 1111 | 1111 1111 | 1111 1111
1.3现在,我们对0xff
进行bitwise and
或( &
,以获取最后8位。
1111 1111 | 1111 1111 | 1111 1111 | 1111 1111 (int -1)
&
0000 0000 | 0000 0000 | 0000 0000 | 1111 1111 (0xff)
=
0000 0000 | 0000 0000 | 0000 0000 | 1111 1111 (last 8 bits)
1.4二进制到十进制计算。
1 1 1 1 1 1 1 1
1, 2, 4, 8, 16, 32, 64, 128 = 255
做完了 对于-1,现在我们有255。
byte aByte = -1;
int number = aByte & 0xff;
System.out.println(number); // output = 255
2. Java 8
Java 8引入了许多新的API以支持无符号操作,例如byte
,现在我们有了Byte.toUnsignedInt()
可以将有符号字节转换为无符号整数。
package com.mkyong.crypto.bytes;
public class Java8UnsignedByte {
public static void main(String[] args) {
byte aByte = (byte) -2; // -2 (signed) and 254 (unsigned)
System.out.println(aByte); // -2
// Java 8
System.out.println(Byte.toUnsignedInt(aByte)); // 254
}
}
查看新的Byte.toUnsignedInt
; Java 8使用相同的技术将字节转换为无符号整数。
public final class Byte extends Number implements Comparable<Byte> {
/*
@since 1.8
*/
public static int toUnsignedInt(byte x) {
return ((int) x) & 0xff;
}
3.旧Java +注释
这个Java示例使用相同的技术,并带有内联注释。 阅读内容不言自明。
package com.mkyong.crypto.bytes;
public class JavaUnsignedByte {
public static void main(String[] args) {
byte input = (byte) -2; // -2 (signed) and 254 (unsigned)
// -2 = 1111 1110 , two's complement
System.out.println("Input : " + input);
// byte (8 bits) cast / widen to int (4 bytes, 16 bits), sign extension will apply
// 1111 1111 | 1111 1111 | 1111 1111 | 1111 1110
int input2 = (int) input;
System.out.println("Input [Binary] : " + Integer.toBinaryString(input2));
// 1111 1111 | 1111 1111 | 1111 1111 | 1111 1110
// &
// 0000 0000 | 0000 0000 | 0000 0000 | 1111 1111 (0xFF) , get last 8 bits
// =============================================
// 0000 0000 | 0000 0000 | 0000 0000 | 1111 1110 unsigned int
int result = input2 & 0xff;
System.out.println(result); // 254
System.out.println(Integer.toBinaryString(result)); // 1111 1110
}
}
参考文献
翻译自: https://mkyong.com/java/java-convert-bytes-to-unsigned-bytes/