【发布时间】:2011-10-21 10:46:06
【问题描述】:
有没有一种简单而优雅的方法可以在 java 中将无符号字节值转换为有符号字节值?例如,如果我只有 int 值 240(二进制(24 位 + 11110000)= 32 位),我怎样才能得到这个 int 的有符号值?
【问题讨论】:
有没有一种简单而优雅的方法可以在 java 中将无符号字节值转换为有符号字节值?例如,如果我只有 int 值 240(二进制(24 位 + 11110000)= 32 位),我怎样才能得到这个 int 的有符号值?
【问题讨论】:
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 为负数,因此强制转换操作用左侧的 1 填充结果 int。 More on java data formats。
那么我们如何从 -112 恢复到正确的 144 值呢?我们需要一个 32 位的 bitmask,我们可以使用 int 创建它:
int mask = 0x000000FF; // This is often shortened to just 0xFF
现在我们可以使用按位& 运算符将最左边的 24 位“清零”,只留下我们原来的 8 位。
int unsignedValue = b & mask; // value = 144
我们的原始值 144 已经恢复,可以安全地转换回一个字节:
byte original = (byte) unsignedValue;
【讨论】:
Java 没有无符号值,char 除外。考虑一下这个 sn-p:
byte val = (byte)255;
System.out.println(String.valueOf(val));
结果将为 -1,因为最低 8 位已复制到字节变量中。
【讨论】:
char 未签名。
在 Java 中,除char 之外的所有基本类型都已签名。你不能有一个无符号字节。
您唯一可以做的就是将无符号字节转换为 int,以便您可以读取其正确值:
int a = b & 0xff
如果你想在字节类型中存储一个无符号字节值,你显然可以,但是每次你需要“处理”它时,只要记得再次转换它,如上所示。
【讨论】:
char 未签名。
Java 仅支持带符号的字节,因此无论何时您将一个值放入一个字节中,它都会被假定为带符号的。
byte b = (byte) 240;
但是,如果您想存储无符号字节,则需要自己处理。 (即Java不支持它,但你可以做到)
对于像 +, -, *, >>, ==, !=, ~ 这样的操作你不需要改变任何东西,对于像 这样的操作你需要做一些小的调整,并且对于 /, % 之类的操作,您需要使用更大的数据类型。
一种常见的替代方法是使用更大的数据类型,例如 int 来存储 0 - 255 之间的值。这样做并没有太大的缺点。
【讨论】: