lv が long 値を格納し、マシンが 32 ビットの場合、次のコード:
iv = int(lv & 0xffffffff)
マシンの int ではなく、long 型の iv が返されます。
この場合、(signed) int 値を取得するにはどうすればよいですか?
import ctypes
number = lv & 0xFFFFFFFF
signed_number = ctypes.c_long(number).value
あなたは高水準のスクリプト言語で作業しています。本来、実行しているシステムのネイティブ データ型は表示されません。このようなコードでネイティブの signed int にキャストすることはできません。
プラットフォームに関係なく、値を 32 ビットの符号付き整数に変換する必要があることがわかっている場合は、次の単純な計算で変換できます。
iv = 0xDEADBEEF
if(iv & 0x80000000):
iv = -0x100000000 + iv
基本的に、Python には任意の大きな整数があるため、問題は 32 ビットから無限のビット数に符号拡張することです。通常、符号拡張はキャスト時に CPU 命令によって自動的に行われるため、これが C などよりも Python で難しいのは興味深いことです。
いろいろ試してみると、BrezhGatch の関数に似たものを見つけましたが、これには条件ステートメントは必要ありません。n & 0x80000000
32 ビットの符号ビットを抽出します。次に、-
同じ 32 ビット表現を保持しますが、符号拡張します。最後に、拡張符号ビットがオンに設定されn
ます。
def toSigned32(n):
n = n & 0xffffffff
return n | (-(n & 0x80000000))
Bit Twiddling Hacksは、おそらくより一般的に機能する別の解決策を提案しています。n ^ 0x80000000
32 ビットの符号ビットを反転します。次に- 0x80000000
、反対のビットを符号拡張します。それについて考える別の方法は、最初は、負の数が正の数の上にあるということです ( で区切られてい0x80000000
ます)。ポジションを^
交換します。次に、-
負の数を 0 未満にシフトします。
def toSigned32(n):
n = n & 0xffffffff
return (n ^ 0x80000000) - 0x80000000
これを提案できますか:
def getSignedNumber(number, bitLength):
mask = (2 ** bitLength) - 1
if number & (1 << (bitLength - 1)):
return number | ~mask
else:
return number & mask
print iv, '->', getSignedNumber(iv, 32)
そのような値を変換するには、構造体ライブラリを使用できます。それは醜いですが、動作します:
from struct import pack, unpack
signed = unpack('l', pack('L', lv & 0xffffffff))[0]
手っ取り早い解決策 (私の場合、x は 32 ビットを超えることはありません)。
if x > 0x7fffffff:
x = x - 4294967296