Pythonの16進数の2の補数

ニムジョックス

aとb(16進数)の下。2の補数の符号付き2進数を表します。例えば:

a = 0x17c7cc6e
b = 0xc158a854

ここで、基数10のaとbの符号付き表現について知りたいと思います。申し訳ありませんが、私は低レベルのプログラマーであり、Pythonを初めて使用します。これを尋ねるのは非常に愚かです。追加のライブラリについては気にしませんが、答えは単純でわかりやすいはずです。背景:aとbは、UDPパケットから抽出されたデータです。私はフォーマットを制御できません。したがって、これらの変数の形式を事前に変更できると想定するような回答はしないでください。

これでaとbを次のように変換しました:

aBinary = bin(int(a, 16))[2:].zfill(32) => 00010111110001111100110001101110 => 398969966
bBinary = bin(int(b, 16))[2:].zfill(32) => 11000001010110001010100001010100 => -1051154348

私はこのようなことをしようとしていました(動作しません):

if aBinary[1:2] == 1:
aBinary = ~aBinary + int(1, 2)

Pythonでこれを行う適切な方法は何ですか?

ヤン・ヴェルニエ

少なくともデータの幅を知っている必要があります。たとえば、0xc158a854には8桁の16進数があるため、少なくとも32ビット幅である必要があります。符号なしの32ビット値のようです。いくつかのビット演算を使用して処理できます。

In [232]: b = 0xc158a854

In [233]: if b >= 1<<31: b -= 1<<32

In [234]: b
Out[234]: -1051154348L

ここでのLは、Python2が値をlongとして処理するように切り替えたことを示しています。通常は重要ではありませんが、この場合は、このインストールの共通のint範囲外の値で作業していることを示しています。UDPパケットなどのバイナリ構造からデータを抽出するツールはstruct.unpackです。値が最初に署名されていることを伝えるだけで、正しい値が生成されます。

In [240]: s = '\xc1\x58\xa8\x54'

In [241]: import struct

In [242]: struct.unpack('>i', s)
Out[242]: (-1051154348,)

これは、2の補数表現を前提としています。1の補数(UDPで使用されるチェックサムなど)、符号と大きさ、またはIEEE 754浮動小数点は、数値のあまり一般的ではないエンコーディングです。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事