我正在尝试将有符号字节转换为无符号字节。问题是我接收的数据是无符号的,而Java不支持无符号字节,所以当它读取数据时,它会将其视为有符号的。
我试着用我从Stack和Overflow得到的解决方案来转换它。
public static int unsignedToBytes(byte a)
{
int b = a & 0xFF;
return b;
}
但是,当它再次转换为字节时,我得到的是相同的带符号数据。我试图将此数据用作Java函数的参数,该函数只接受一个字节作为参数,因此不能使用任何其他数据类型。我如何解决这个问题?
发布于 2010-11-24 20:40:22
我不太明白你的问题。
我刚刚试过了,对于字节12(有符号值),它返回整数244 (等同于无符号字节值,但类型为int
):
public static int unsignedToBytes(byte b) {
return b & 0xFF;
}
public static void main(String[] args) {
System.out.println(unsignedToBytes((byte) -12));
}
这是你想做的吗?
Java不允许将244表示为127值,就像C一样。要表示Byte.MAX_VALUE
(127)以上的正整数,您必须使用不同的整数类型,如short
、int
或long
。
发布于 2010-11-24 20:36:29
在Java中,原语是带符号的,这与它们在内存/传输中的表示方式无关--一个字节只有8位,您是否将其解释为带符号的范围取决于您。没有神奇的旗帜来表示“这是已签名的”或“这是未签名的”。
由于对原语进行了签名,Java编译器将阻止您为一个字节分配高于+127的值(或小于-128的值)。然而,为了实现这一点,没有什么可以阻止您向下转换int (或short):
int i = 200; // 0000 0000 0000 0000 0000 0000 1100 1000 (200)
byte b = (byte) 200; // 1100 1000 (-56 by Java specification, 200 by convention)
/*
* Will print a negative int -56 because upcasting byte to int does
* so called "sign extension" which yields those bits:
* 1111 1111 1111 1111 1111 1111 1100 1000 (-56)
*
* But you could still choose to interpret this as +200.
*/
System.out.println(b); // "-56"
/*
* Will print a positive int 200 because bitwise AND with 0xFF will
* zero all the 24 most significant bits that:
* a) were added during upcasting to int which took place silently
* just before evaluating the bitwise AND operator.
* So the `b & 0xFF` is equivalent with `((int) b) & 0xFF`.
* b) were set to 1s because of "sign extension" during the upcasting
*
* 1111 1111 1111 1111 1111 1111 1100 1000 (the int)
* &
* 0000 0000 0000 0000 0000 0000 1111 1111 (the 0xFF)
* =======================================
* 0000 0000 0000 0000 0000 0000 1100 1000 (200)
*/
System.out.println(b & 0xFF); // "200"
/*
* You would typically do this *within* the method that expected an
* unsigned byte and the advantage is you apply `0xFF` only once
* and than you use the `unsignedByte` variable in all your bitwise
* operations.
*
* You could use any integer type longer than `byte` for the `unsignedByte` variable,
* i.e. `short`, `int`, `long` and even `char`, but during bitwise operations
* it would get casted to `int` anyway.
*/
void printUnsignedByte(byte b) {
int unsignedByte = b & 0xFF;
System.out.println(unsignedByte); // "200"
}
发布于 2010-11-24 20:36:33
在Java中使用无符号字节的完整指南:
(此答案的来源。)
Java语言没有提供任何类似于unsigned
关键字的东西。根据语言规范的byte
表示介于−128 - 127之间的值。例如,如果将byte
转换为int
,Java会将第一位解释为符号并使用sign extension。
也就是说,没有什么可以阻止您简单地将byte
视为8位,并将这些位解释为0到255之间的值。请记住,您无法将您的解释强加于其他人的方法。如果方法接受byte
,则该方法接受介于−128和127之间的值,除非另有明确说明。
为了方便起见,这里有几个有用的转换/操作:
与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));
https://stackoverflow.com/questions/4266756
复制相似问题