31

lv が long 値を格納し、マシンが 32 ビットの場合、次のコード:

iv = int(lv & 0xffffffff)

マシンの int ではなく、long 型の iv が返されます。

この場合、(signed) int 値を取得するにはどうすればよいですか?

4

6 に答える 6

35
import ctypes

number = lv & 0xFFFFFFFF

signed_number = ctypes.c_long(number).value
于 2012-02-19T17:13:34.500 に答える
21

あなたは高水準のスクリプト言語で作業しています。本来、実行しているシステムのネイティブ データ型は表示されません。このようなコードでネイティブの signed int にキャストすることはできません。

プラットフォームに関係なく、値を 32 ビットの符号付き整数に変換する必要があることがわかっている場合は、次の単純な計算で変換できます。

iv = 0xDEADBEEF
if(iv & 0x80000000):
    iv = -0x100000000 + iv
于 2009-09-03T21:03:04.310 に答える
16

基本的に、Python には任意の大きな整数があるため、問題は 32 ビットから無限のビット数に符号拡張することです。通常、符号拡張はキャスト時に CPU 命令によって自動的に行われるため、これが C などよりも Python で難しいのは興味深いことです。

いろいろ試してみると、BrezhGatch の関数に似たものを見つけましたが、これには条件ステートメントは必要ありません。n & 0x8000000032 ビットの符号ビットを抽出します。次に、-同じ 32 ビット表現を保持しますが、符号拡張します。最後に、拡張符号ビットがオンに設定されnます。

def toSigned32(n):
    n = n & 0xffffffff
    return n | (-(n & 0x80000000))

Bit Twiddling Hacksは、おそらくより一般的に機能する別の解決策を提案しています。n ^ 0x8000000032 ビットの符号ビットを反転します。次に- 0x80000000、反対のビットを符号拡張します。それについて考える別の方法は、最初は、負の数が正の数の上にあるということです ( で区切られてい0x80000000ます)。ポジションを^交換します。次に、-負の数を 0 未満にシフトします。

def toSigned32(n):
    n = n & 0xffffffff
    return (n ^ 0x80000000) - 0x80000000
于 2016-05-08T03:17:02.927 に答える
9

これを提案できますか:

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)
于 2012-07-23T12:22:44.607 に答える
9

そのような値を変換するには、構造体ライブラリを使用できます。それは醜いですが、動作します:

from struct import pack, unpack
signed = unpack('l', pack('L', lv & 0xffffffff))[0]
于 2009-09-07T16:53:49.193 に答える
4

手っ取り早い解決策 (私の場合、x は 32 ビットを超えることはありません)。

if x > 0x7fffffff:
    x = x - 4294967296
于 2016-06-27T22:34:28.467 に答える