5

JavaScriptでビットマスクを作成しています。-2147483648ビット 0 から 14 まで正常に動作します。ビット 15 のみを 1 に設定すると、" " ではなく" " の整数値が生成されます2147483648。ハードコーディングされた " " をビット 15 に返すことで、ここで特殊なケースのハックを行うことができますが2147483648、その正しい方法を知りたいです。

サンプルコード:

function join_bitmap(hex_lower_word, hex_upper_word)
{
    var lower_word = parseInt(hex_lower_word, 16);
    var upper_word = parseInt(hex_upper_word, 16);
    return (0x00000000ffffffff & ((upper_word<<16) | lower_word));
}

上記のコードは、hex_lower_word が「0x0」で hex_upper_word が「0x8000」の場合、2147483648 ではなく -2147483648 を返します。

4

3 に答える 3

3

これは、Javascript のビット シフト操作が符号付き 32 ビット整数を使用するためです。したがって、これを行う場合:

0x1 << 31   // sets the 15th bit of the high word

符号ビットを 1 に設定します。これは負を意味します。

一方、ビット シフトの代わりに 2 の累乗を乗算すると、必要な結果が得られます。

1 * Math.pow(2, 31)
于 2013-02-04T19:41:13.947 に答える
2

その理由は、あなたが設定していることsign bitです...

2147483648バイナリで 1 の後に 31 個のゼロが続きます...

ビット単位の操作を行っているため、出力は常に符号付きの 32 ビット数であり、32 番目のビットが符号ビットになるため、負の数が得られます...

アップデート

(upper_word * Math.pow(2, 16))

正を与え2147483648ます。

しかし、あなたにはまだOR手術があり、振り出しに戻ります...

于 2013-02-04T19:43:14.853 に答える
1

前の回答で説明したように、ビット演算子は 32 ビット符号付きです。したがって、途中でビット 31 を設定すると、事態は大きく悪化します。

あなたのコードでは、式

(upper_word<<16) | lower_word)

は括弧のために最初に評価され、upper_word には最上位ビットが設定されているため、負の数 ( 0x80000000 = -2147483648)になります。

解決策は、a をビット 31 にシフトしないようにすることです。そのため、シフトする1前に上位ワードのビット 15 をゼロに設定する必要があります。

mask15 = 0x7fff;
((upper_word&mask15)<<16|lower_word)

これは「大きすぎる数値が負になる」ことを処理しますが、問題を完全に解決するわけではありません-間違った答えを与えるだけです! 正しい答えに戻るには、ビット 15 が upper_word に設定されている場合、答えのビット 31 を設定する必要があります。

bit15 = 0x8000;
bit31 = 0x80000000;
answer = answer + (upper_word & bit15)?bit31:0; 

書き直された関数は次のようになります。

function join_bitmap(hex_lower_word, hex_upper_word)
    {
        var lower_word = parseInt(hex_lower_word, 16);
        var upper_word = parseInt(hex_upper_word, 16);
        var mask15 = 0x7fff;
        var bit15 = 0x8000;
        var bit31 = 0x80000000;
        return 0xffffffff & (((upper_word&mask15)<<16) | lower_word) + ((upper_word & bit15)?bit31:0);
    }

「ハードコードされた特殊なケース」は 1 つだけではなく、20 億程度あります。これにより、それらすべてが処理されます。

于 2013-02-04T20:25:46.060 に答える