首页 文章

如何在Java中存储(一组)无符号字节来对它们进行位操作?

提问于
浏览
0

我需要在Java中存储(一组)无符号字节来对它们进行位操作 . 我想做标准的位操作 . shift ((sVal>>8) & 0xff); ,或|,和&,以及比较 . 和 w |= ~0xff; 如何存储它们?

字节b = 0x96; //值为150

我得到一个编译错误:类型不匹配:无法从int转换为byte

所以我投了它

byte b =(cast)0x96;

现在我看到值已变为-106 .

如果我存储为char,则会将其提升为2个字节 .

我应该如何将值存储为Java中的无符号字节,以便我可以对它们进行一些操作?

使用 int 会有问题吗?

4 回答

  • 1

    如果你没有做涉及算术的符号,使用位操作(除了unsigned-shift-right)没有问题 .

    是的,转换为char或int会扩展符号,但您可以执行以下操作:

    byte b = (byte)0x96;
    int n = 0xFF & b; // Again 0..255
    

    (也许应该警告,尝试将字节存储在带字符的字符串中,是一种涉及编码转换的滥用 . )

    顺便说一句,类Integer, Long and such有许多有趣的位操作 . BitSet类也是一个有趣的游乐场 .

  • 1

    Java中没有无符号的原始数据类型 - 字节是有符号的 . 您需要找出一些其他方式来表示您的数据,具体取决于您想要做什么 .

    编辑:

    人们已经给了你一些建议和解释,你没有解释你的情况的要求('很多和快速'没有帮助) . 但我注意到你原来的帖子还有其他的东西 .

    你说

    byte b =(cast)0x96;现在我看到值已变为-106 .

    我想知道你是否理解字节的值根本没有变化 . 该字节仍然是十六进制96,你可以看到,如果你用十六进制打印出来 . -106仅是由十六进制96表示的十进制数 .

    如果您要做的只是位操作,那么您仍然可以将其全部存储为字节 . 只有当你还需要算术运算时 - 加,减,多,除,大于,小于 - 你需要担心字节的带符号性质 .

  • 3

    您可以对有符号字节进行一些操作 - 它们会产生您期望的相同结果 . 你必须注意的一件事是 >> ;如果有符号字节为负,这将填充最左边的位,但如果使用 >>> (三个 > 符号),它将始终用0填充最左边的位,这实质上将其视为无符号字节,即使它已经签名 .

    如果您想要一个字节的整数值,并且您想要一个0到255之间的值:

    int value = ((int)yourByte) & 0xFF;
    

    或者,在Java 8中,您可以使用Byte.toUnsignedInt .

    [实际上,演员没有必要,因为 yourByte0xFF 会在应用_2583830之前自动升级到 int . 但是,如果没有查找,我就永远不会记住这条规则,所以显式演员对我有帮助 . ]

    如果要对两个字节(或一个字节和一个整数文字)进行有序比较并将它们视为无符号,则可以使用上述方法之一将它们转换为 int 并比较 int .

  • 2

    您可以对字节使用二进制操作而没有任何限制,只需要小心右移,这取决于您愿意实现的目标 . 使用 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));
        }
    

相关问题