ActionScript 3 中的按位运算与 Java 比较

Bitwise operation in ActionScript 3 compare to Java

我正在研究将 BitString 写入 ByteArray 的 AS3 代码。资料来源:JPGEncoder#writeBits()

private var byteout:ByteArray;
private var bytenew:int = 0;
private var bytepos:int = 7;

private function writeBits(bs:BitString):void
{
    var value:int = bs.val;
    var posval:int = bs.len-1;
    while (posval >= 0) {
        if (value & uint(1 << posval)) {
            bytenew |= uint(1 << bytepos);
        }
        posval--;
        bytepos--;
        if (bytepos < 0) {
            if (bytenew == 0xFF) {
                writeByte(0xFF);
                writeByte(0);
            } else {
                writeByte(bytenew);
            }
            bytepos=7;
            bytenew=0;
        }
    }
}

但是我不明白部分代码。

这些 AS3 代码在 Java 中等效于什么?

我相信这些是 AS3 的移位运算符。您会发现 Java 使用相同的语法。

link about bit operations in AS3. The Java documentation page here 解释了运算符的作用。

至于 if 条件,它检查 value 中从右边算起的第 'posval' 位是否为 1。它 "selects" 该位由在 value 之间应用 bitwise and 并将值 1(二进制 000...01)移动 posval 位。

Java 中的位运算有点笨拙,因为 Java 没有无符号类型。 因此,当您打算使用字节时,您应该确保使用字节。 0x0f之类的东西 | 0x80 -> 0b1000 1111 完成字节必须始终转换为字节:

System.out.printf("%x - %x - (byte)%x - (int)%x\n", 
                   (byte)0x80, 
                   (byte)0xf, 
                   (byte)((byte)0x80|(byte)0xf), 
                    (int)((byte)0x80|(byte)0xf));

OUTPUT:
80 - f - (byte)8f - (int)ffffff8f

话虽如此,您可能希望从一开始就使用整数,然后再转换为字节。

您提供的代码将 BitString 转录为切成字节的比特流。

如果设置了一个字节的所有位,则处理特殊情况,在这种情况下输出 0xff00。

What is uint(1 << bytepos)?

这会将运算符的 lhs 向左移动 bytepos 位:

1 << 4 -> 0b00010000

What is the if condition if (value & uint(1 << posval))? I don't know whether the & is "and" bit operator, or "and" condition.

& 是按位与,&& 是布尔值。

如果设置了posval位置的位,则操作是!= 0 -> TRUE。这是设置字节中相应位的条件。

将代码转移到 Java 实际上应该很简单。我建议您在 java 中使用纯 int 并在写入之前转换为字节:

byte realByte = (byte)(intbyte & (byte)0xff);
writeByte(realByte);

通过这种方式,您可以避免常量转换为字节,也可以避免上面提到的负字节问题。