1

Javaでの値を決定するために必要な3バイトの符号付き数値があります。私はそれが1の補数で署名されていると信じていますが、100%確信はありません(私はこのことを10年以上研究しておらず、私の問題の文書化はあまり明確ではありません)。私が抱えている問題は、Javaが2の補数ですべてを実行することだと思います。示す具体的な例があります。

  • 元の3バイトの数値:0xEE1B17

  • 整数(Integer.parseInt(s, 16))として解析すると、次のようになります:15604503

  • これを簡単にビットフリップ(~)すると、2の補数表現が得られます(と思います):-15604504

  • しかし、私が取得する必要がある値は次のとおりです。-1172713

私が起こっていると思うのは、intの3バイトだけでなく、int全体の2の補数を取得しているということですが、これを修正する方法がわかりません。

私ができることは、整数を2進文字列(Integer.toBinaryString())に変換してから、すべての0を1に、またはその逆に手動で「反転」することです。次に、この整数(Integer.parseInt(s, 16))を解析すると、非常に近い1172712が得られます。他のすべての例では、答えを得るために常に結果に1を追加する必要があります。

ここで使用されている符号付き数値エンコーディングのタイプを診断できますか?また、文字列のすべての文字を手動で反転する以外の解決策があるかどうかを診断できますか?これを行うにはもっとエレガントな方法があるに違いないと思います。

編集:すべてのレスポンダーはさまざまな方法で助けてくれましたが、私の一般的な質問は3バイトの数字を反転する方法で、@ louis-wassermanがこれに答えて最初に答えたので、彼を解決策としてマークします。助けてくれたみんなに感謝します!

4

3 に答える 3

2

Java int の下位 3 バイトを反転したい場合は、^ 0x00FFFFFF.

于 2013-02-04T19:59:11.147 に答える
1

0xFFEE1B17is -1172713 先頭のバイトのみを追加する必要があります。FF3 バイト値の最上位ビットが設定されている場合と00そうでない場合。

3 バイト値を適切な値に変換するメソッドは次のintようになります。

if(byte3val>7FFFFF)
  return byte3val| 0xFF000000;
else 
  return byte3val;
于 2013-02-04T19:59:49.880 に答える
0

負の符号付きの数値は、 のように定義されa + (-a) = 0ます。したがって、すべてのビットが反転されてから1追加されることを意味します。2 の補数を参照してください。を加えるとどうなるかを考えれば、この過程で条件が満たされていることが確認できますa + ~a + 1

最上位ビットによって数値が負であることを認識できます。したがって、符号付きの 3 バイトの数値を 4 バイトの数値に変換する必要がある場合は、ビットをチェックして、それが設定されている場合は、4 番目のバイトのビットも設定することで実行できます。

if ((a & 0x800000) != 0)
    a = a | 0xff000000;

計算に分岐がないため、単一の式で実行することもできます (分岐は現在の CPU のパイプライン処理ではうまく機能しません)。

a = (0xfffffe << a) >> a;

ここで、バイトシフト<<を実行します。>>まず、数値 8 ビットを右にシフトし (したがって、3 つの「下位」バイトではなく 3 つの「上位」バイトを占有します)、次にシフトバックします。秘訣は、それが符号付きシフトと>>呼ばれる算術シフトです。操作によって空になったすべてのビットに最上位ビットをコピーします。これはまさに数字の符号を保持するためです。それはそう:

(0x1ffffe << 8) >> 8        ->  2097150
(0xfffffe << 8) >> 8        ->  -2

Java にも符号なし右シフト演算子があることに注意してください>>>。詳細については、「Java チュートリアル:ビット単位およびビット シフト演算子」を参照してください。

于 2013-02-04T20:08:23.433 に答える