1

以下に説明するように、負の数の FIX/FAST デコーダーを作成しています。

ここに画像の説明を入力

私の質問は:

上記のように、Javaバイトのハイエンドビットを1で埋める方法は? 私はおそらく、この変換で必要なビット操作の魔法に気づいていません。

したがって、01000110 00111010 01011101 から 11110001 10011101 01011101 に移動する必要があります。

7 だけシフトして 8 番目のビットを削除する方法を知っています。私が知らないのは、ハイエンド ビットを 1 で埋める方法です。

4

5 に答える 5

2

あなたが尋ねている質問は、解決しようとしている問題と実際には一致していないようです。1上位ビットを;で埋めようとしているわけではありません。バッファからストップビットでエンコードされた整数をデコードしようとしています。これには、ペイロードビットを結合する際に符号ビットを破棄することが含まれます。1もちろん、ストップ ビット位置にa があるバイトを見つけたら停止します。以下のメソッドは、値を正しくデコードする必要があります。

private static final byte SIGN_BIT = (byte)0x40;
private static final byte STOP_BIT = (byte)0x80;
private static final byte PAYLOAD_MASK = 0x7F;

public static int decodeInt(final ByteBuffer buffer) {
    int value = 0;
    int currentByte = buffer.get();

    if ((currentByte & SIGN_BIT) > 0)
        value = -1;

    value = (value << 7) | (currentByte & PAYLOAD_MASK);
    if ((currentByte & STOP_BIT) != 0)
        return value;

    currentByte = buffer.get();
    value = (value << 7) | (currentByte & PAYLOAD_MASK);
    if ((currentByte & STOP_BIT) != 0)
        return value;

    currentByte = buffer.get();
    value = (value << 7) | (currentByte & PAYLOAD_MASK);
    if ((currentByte & STOP_BIT) != 0)
        return value;

    currentByte = buffer.get();
    value = (value << 7) | (currentByte & PAYLOAD_MASK);
    if ((currentByte & STOP_BIT) != 0)
        return value;

    currentByte = buffer.get();
    value = (value << 7) | (currentByte & PAYLOAD_MASK);
    return value;
}

ループはよりクリーンになりますが、メッセージング プロトコルはホット コード パスになる傾向があり、固定された最大バイト長 (5 バイト) があるため、手動で展開しました。簡単にするために、 a からバイトを読み取るためByteBuffer、エンコードされたデータの読み取り方法に基づいてロジックを調整する必要がある場合があります。

于 2014-09-05T18:09:16.017 に答える
1

これは、一度に 7 ビットをシフトする単純なアキュムレータを使用して非常に簡単に行うことができます。アキュムレータにあるビット数を追跡​​する必要があります。

符号拡張は、単純な論理左シフトとそれに続く算術右シフト (同じ距離) によって実行でき、最上位ビットを未使用のすべての位置にコピーできます。

byte[] input = new byte[] { 0x46, 0x3A, (byte) 0xDD };
int accumulator = 0;
int bitCount = 0;
for (byte b : input) {
    accumulator = (accumulator << 7) | (b & 0x7F);
    bitCount += 7;
}
// now sign extend the bits in accumulator
accumulator <<= (32 - bitCount);
accumulator >>= (32 - bitCount);
System.out.println(Integer.toHexString(accumulator));

全体のトリックは、 >>N 演算子がトップビットを N 回複製することです。

于 2014-09-05T17:04:23.230 に答える
0

上位ビットが 1 に設定され、残りが 0 である数値で論理OR( ) を実行します。|

例えば:

   1010101010101010
OR 1111111100000000
--------------------
   11111111101010101
于 2014-09-05T15:07:41.860 に答える
0

このようなもの:

int x = ...; x = x | 0xF000;

于 2014-09-05T15:09:39.640 に答える