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

9

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

5个回答

27

在Java中,除了char外,所有原始数据类型都是有符号的。你不能拥有一个无符号的字节。

唯一可以做的就是将无符号的字节转换为整数,这样您就可以读取其正确的值:

int a = b & 0xff

如果你想在byte类型中存储一个无符号的Byte值,显然可以这样做,但每次需要“处理”它时,请记得像上面展示的那样再次将其转换。


这会有什么影响?这是否意味着,如果b是32位整数,则将其与11111111进行“and”操作将复制最低的8位?谢谢。 - Joeblackdev
抱歉,我忘了提到“b”是保存在有符号字节类型中的无符号字节(唯一可用)。您始终可以将无符号字节存储在有符号字节类型中,但每次需要进行某些数学运算时都需要执行上述转换。如果您只需要检查其位,则不需要这样做。 - ostefano
我还没有明白你的意思。为什么要将字节b与0xff相与? - Joeblackdev
1
这意味着你将值向上转换为另一种类型(在Java中,你不能将0xFF赋给一个字节变量),并且丢弃除右侧8位(存储值的位置)以外的所有位。 - ostefano
1
在Java中,所有基本类型都是有符号的。:不是真的。 char 是无符号的。 - Nayuki
@NayukiMinase 没错,我忘了那个。谢谢你指出来。 - ostefano

9

Java没有无符号值,除了char。考虑下面的代码片段:

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

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

我明白你的意思。在Java中,int类型是32位的,所以最低的8位会被复制,对吗? - Joeblackdev
2
是的。在这里,“最低位”指的是具有最低位置值(2^n)的位。因此,具有位置值2^0 - 2^7的位被复制,但具有值2^8或更高的位被丢弃。由于这是Java,您不需要担心字节序。 - Tassos Bassoukos
另外,如果您想使用无符号值进行处理,请按照@ostefano编写的方式操作 - 在任何情况下,Java都会针对int、short和byte进行整数运算。 - Tassos Bassoukos
3
Java没有无符号的值:不准确。char是无符号类型。 - Nayuki

8
以下是如何存储和转换无符号字节值的方法:
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是负数,所以强制类型转换操作从左边用1填充生成的整数。更多关于Java数据格式的信息
那么我们如何从-112恢复到正确的值144呢?我们需要一个32位的位掩码,可以使用int创建:
int mask = 0x000000FF; // This is often shortened to just 0xFF

现在我们可以使用位运算符&来“清除”最左边的24位,只留下我们原始的8位。
int unsignedValue = b & mask; // value = 144

我们原始的值为144已经恢复,并且可以安全地转换回一个字节:
byte original = (byte) unsignedValue;

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

应该做好这项工作。

2

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

byte b = (byte) 240;

然而,如果您想存储无符号字节,则需要自己处理(即Java不支持但您可以实现)。对于像+、-、*、<<、>>>、==、!=、~这样的操作,您不需要更改任何内容。对于像<、>这样的操作,您需要进行微小的调整,而对于像/、%这样的操作,您需要使用更大的数据类型。一个常见的替代方案是使用更大的数据类型,如int来存储0-255的值。这样做没有太多的缺点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接