将无符号字节转换为有符号字节

有没有一种简单而优雅的方法可以将无符号字节值转换为java中的有符号字节值? 例如,如果我只有int值240(二进制(24位+ 11110000)= 32位),我如何获得此int的有符号值?

char之外,Java没有无符号值。 考虑以下代码段:

 byte val = (byte)255; System.out.println(String.valueOf(val)); 

结果将为-1,因为最低的8位被复制到字节变量。

在Java中,除char之外的所有原始类型都是有符号的。 你不能有一个无符号字节。 您可以做的唯一事情是将无符号字节转换为int,以便您可以读取其正确的值:

 int a = b & 0xff 

如果你想在字节类型中存储一个无符号字节值,你显然可以,但每次你需要“处理”它时,只需记住如上所示再次强制转换它。

 public int getUnsignedByte(byte[] bytes, int offset) { return (bytes[offset] & 0xFF); } 

应该做的工作。

以下是存储和转换无符号字节值的方法:

 byte b = (byte) 144; // binary value = 10010000 

如果你将b转换为int ,那么会发生什么:

 int i = b; System.out.println("value: "+i); System.out.println("binary: " + Integer.toBinaryString(i)); 

输出:

 value: -112 <- Incorrect value binary: 11111111111111111111111110010000 

为什么会这样? 字节用Java签名, b是负数,因此强制转换操作用左边的1s填充结果int。 有关Java数据格式的更多信息

那么我们如何从-112回到144的正确值呢? 我们需要一个32位的位掩码 ,我们可以用int创建它:

 int mask = 0x000000FF; // This is often shortened to just 0xFF 

现在我们可以使用bitwise &运算符将最左边的24位“归零”,只保留原来的8位。

 int unsignedValue = b & mask; // value = 144 

我们的原始值144已经恢复,可以安全地返回到一个字节:

 byte original = (byte) unsignedValue; 

Java只支持有符号字节,所以无论何时在一个字节中放置一个值,它都会被认为是有符号的。

 byte b = (byte) 240; 

但是,如果要存储无符号字节,则需要自己处理。 (即Java不支持它,但你可以这样做)

对于像+, – ,*,<<,>>>,==,!=,〜这样的操作,你不需要改变任何东西,对于像<,>这样的操作,你需要进行微小的调整,以及像/,%您需要使用更大的数据类型。

一种常见的替代方法是使用更大的数据类型(如int来存储值0到255.这样做没有太大的缺点。