如何从比特流中组装字节?

时间:2015-12-12 23:10:24

标签: java

我正在尝试用Java语言中的单个位/布尔值来源创建字节。我希望例程能够尽快运行,并且我遵循无符号的字节风格。我已经完成了一些互联网搜索,但实际上找不到任何特定的代码。

所有我能想到的是以下,这似乎是业余的。我知道BitSet,但那些内部表示为Longs(我使用的是32位机器,所以双重处理)并且它有一个巨大的API,所以我希望它很慢。可以有更高效的东西,也许是低水平的吗?

public int nextByte() {
    int b = 0;


    for (int k = 0; k < 7; k++) {
        if (nextBoolean()) {
            b++;
        }


        b = b << 1;
    }


    if (nextBoolean()) {
        b++;
    }


    return b;
}

1 个答案:

答案 0 :(得分:1)

这应该尽可能高效:

public int nextByte() {
    int b = nextBoolean() ? 0x80 : 0;

    if (nextBoolean()) b = b | 0x40;
    if (nextBoolean()) b = b | 0x20;
    if (nextBoolean()) b = b | 0x10;
    if (nextBoolean()) b = b | 0x08;
    if (nextBoolean()) b = b | 0x04;
    if (nextBoolean()) b = b | 0x02;
    if (nextBoolean()) b = b | 0x01;

    return b;
}

如果您想尝试真的,真的很难,您可以使用:

public int nextByte() {
    return
        (nextBoolean() ? 0x80 : 0)
        | (nextBoolean() ? 0x40 : 0)
        | (nextBoolean() ? 0x20 : 0)
        | (nextBoolean() ? 0x10 : 0)
        | (nextBoolean() ? 0x08 : 0)
        | (nextBoolean() ? 0x04 : 0)
        | (nextBoolean() ? 0x02 : 0)
        | (nextBoolean() ? 0x01 : 0);
}

如果这是C语言,那么最后一个解决方案 not 无法保证正常工作,因为C标准认为对nextBoolean()的调用可能以编译器认为合适的任何顺序发生。但是,the Java Language Specification15.7部分保证(明显)严格的从左到右的评估,所以在Java中, 保证按正确的顺序排列。另一方面,下一句明确建议代码“不要严格依赖于此规范”,并且“当每个表达式最多包含一个副作用时,代码通常更清晰”。当然,调用nextBoolean()是“副作用”的教科书示例,并且在单个表达式中执行8次违反了该建议。

此外(最重要的是,与其他答案一致),我说这些解决方案中计算成本最高的部分(或者你的解决方案)可能是对nextBoolean()的八次调用,而不是循环或条件,所以我认为如果不避免这些电话,你可以明显加快这一点。