我试图转换一个无符号的有符号字节。问题是我接收的数据是无符号的,Java不支持无符号字节,所以当它读取数据时,它将其视为有符号的。
我尝试通过下面的解决方案转换它,我从Stack Overflow。
public static int unsignedToBytes(byte a)
{
int b = a & 0xFF;
return b;
}
但是当它再次以字节为单位转换时,我得到了相同的带符号数据。我试图使用此数据作为参数的Java函数,只接受一个字节作为参数,所以我不能使用任何其他数据类型。我该如何解决这个问题?
在Java中使用unsigned字节的完整指南:
Java中的无符号字节
(答案来源)
Java语言不提供任何类似unsigned关键字的东西。根据语言规范,一个字节表示−128 - 127之间的值。例如,如果将一个字节转换为int类型,Java将把第一位解释为符号并使用符号扩展。
也就是说,没有什么可以阻止您将一个字节简单地视为8位,并将这些位解释为0到255之间的值。只要记住,你不能把你的解释强加给别人的方法。如果一个方法接受一个字节,那么该方法接受−128到127之间的值,除非另有明确说明。
下面是一些有用的转换/操作,方便您使用:
从int到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));
算法
2补表示“只适用于”加法、减法和乘法:
// 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));
你还可以:
public static int unsignedToBytes(byte a)
{
return (int) ( ( a << 24) >>> 24);
}
解释:
假设a = (byte) 133;
在内存中,它被存储为:"1000 0101"(十六进制中的0x85)
所以它的表示可以转换为unsigned=133, signed=-123(作为2的补码)
A << 24
当向左移动24位时,结果现在是一个4字节的整数,表示为:
"10000101 00000000 00000000 00000000"(或十六进制中的"0x85000000")
然后我们有
(a << 24) >>>
它又向右移动了24位,但前导都是0。结果是:
"00000000 00000000 00000000 10000101"(或十六进制中的"0x00000085")
这就是无符号表达式它等于133。
如果你试图强制转换a = (int) a;
然后会发生的是,它保留了字节的2补表示,并将其存储为int,同时也存储为2的补:
(int)“10000101”——>“11111111 11111111 11111111 10000101”
翻译过来就是-123