我需要在Java中存储(一组)无符号字节来对它们进行位操作。
我想做标准的位操作。转移((sVal>>8) & 0xff);
,或|,和&,以及比较。和w |= ~0xff;
之类的东西
我该如何存储它们?
字节b = 0x96; //值为150
我收到编译错误:类型不匹配:无法从int转换为byte
所以我投了它
字节b =(强制转换)0x96;
现在我看到值已更改为-106。
如果我将其存储为char,则会将其提升为2个字节。
我应该如何将值存储为Java中的无符号字节,以便我可以对它们进行一些操作?
使用 int 会出现问题吗?
答案 0 :(得分:3)
Java中没有无符号的原始数据类型 - 字节是有符号的。您需要找出其他方式来表示您的数据,具体取决于您想要做什么。
编辑:
人们已经给了你一些建议和解释,你还没有解释你的情况要求(很多人都很快,并没有帮助) 。但我注意到你原来的帖子还有别的东西。
你说
byte b = (cast) 0x96;
现在我看到值已更改为-106。
我想知道您是否理解该字节的值根本没有变化。该字节仍然是十六进制96,你可以看到,如果你用十六进制打印出来。 -106只是十六进制96表示的十进制数。
如果您要做的只是位操作,那么您可以将其全部存储为字节。只有当你还需要算术运算时 - 加,减,多,除,大于,小于 - 你需要担心字节的带符号性质。
答案 1 :(得分:2)
如果你没有做涉及算术的符号,使用位操作(除了unsigned-shift-right)没有问题。
是的,转换为char或int会扩展符号,但您可以这样做:
byte b = (byte)0x96;
int n = 0xFF & b; // Again 0..255
(也许应该警告,尝试将字节存储在带字符的字符串中,是一种涉及编码转换的滥用行为。)
顺便说一句,类Integer, Long and such有许多有趣的位操作。 BitSet类也是一个有趣的游乐场。
答案 2 :(得分:1)
您可以对有符号字节进行一些操作 - 它们会产生您期望的相同结果。你必须注意的一件事是>>
;如果有符号字节为负,这将填充最左边的位1,但如果使用>>>
(三个>
符号),它将始终用0填充最左边的位,这实质上是对它进行处理就像一个无符号字节,即使它已经签名。
如果你想要一个字节的整数值,你想要一个0到255之间的值:
int value = ((int)yourByte) & 0xFF;
或者,在Java 8中,您可以使用Byte.toUnsignedInt
。
[实际上,演示文稿不是必需的,因为yourByte
和0xFF
会在应用int
之前自动升级为&
。但是,如果没有查找,我就永远不会记住这条规则,所以明确的演员阵容对我很有帮助。]
如果要对两个字节(或一个字节和一个整数文字)进行有序比较并将它们视为无符号,可以使用上述方法之一将它们转换为int
并比较{ {1}}秒。
答案 3 :(得分:1)
您可以对字节使用二进制操作而不受任何限制,只需要小心右移,这取决于您愿意实现的目标。使用Integer.toBinaryString(int i)
,您可以看到正在发生的事情,尽管它不是最好的代表:
public static void main(String[] args) {
byte b1 = (byte) 0x96;
int i1 = b1 & 0xFF;
System.out.println(Integer.toBinaryString(i1));
byte b2 = (byte) (b1 << 1);
int i2 = b2 & 0xFF;
System.out.println(Integer.toBinaryString(i2));
System.out.println(Integer.toBinaryString(i1 & i2));
}