2009-09-03 3 views

ответ

13

Вы работаете на высокоуровневом языке сценариев; по своей природе, собственные типы данных используемой системы не отображаются. Вы не можете отнести к встроенному подписанному int с таким кодом.

Если вы знаете, что вы хотите, значение преобразуется в 32-разрядное целое число - независимо от платформы - вы можете просто сделать преобразование с простой математикой:

iv = 0xDEADBEEF 
if(iv & 0x80000000): 
    iv = -0x100000000 + iv 
+0

Это неточно: все вычисления, которые вписываются в слово машины, выполняются на этом уровне. Например, ~ 1 == -2. Итак, я ищу способ заставить результат ввести тип int (что не является тем, что делает int(), по-видимому). – 2009-09-04 19:27:43

+0

~ 1 == -2 в Python на * все * системах. Если это не так в собственной системе, то реализация Python должна эмулировать ее. (См. Http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy.) Единственный раз, когда размер родного слова может протекать в Python, когда размер int больше 32 бит , что означает, что вы делаете transtion от int до более позднего. –

+0

Вы не можете заставить Python преобразовывать long в int, когда значение не помещается в int; вы не можете писать код Python, как если бы вы были на C.Если вы хотите преобразовать 32-битное значение без знака 0xFFFFFFFF в 32-битное целое число со знаком, представленное одной и той же битовой строкой, то я дал вам код. В противном случае я не уверен, что вы пытаетесь сделать. –

5

Вы можете использовать struct библиотека для преобразования таких значений. Это некрасиво, но работает:

from struct import pack, unpack 
signed = unpack('l', pack('L', lv & 0xffffffff))[0] 
+0

Это работает на 32-битных машинах и не работает на 64-разрядном – nkrkv

+3

Это можно сделать переносным, если вы используете один из символов порядка/размера/выравнивания. Например, используйте '' = l'' и '' = L'' в качестве строк формата. – SamB

19
import ctypes 

number = lv & 0xFFFFFFFF 

signed_number = ctypes.c_long(number).value 
6

Могу ли я предположить, что это:

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) 
5

По сути, проблема заключается в знаке простираться от 32 до ... бесконечного числа бит, потому что Python имеет сколь угодно большие целые числа. Обычно расширение знака выполняется автоматически инструкциями ЦП при кастинге, поэтому интересно, что это сложнее в Python, чем в, скажем, C.

Поиграв, я нашел нечто похожее на функцию BreizhGatch, но это не требует условного утверждения. 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 
+0

+1 для не используется условные обозначения. Вероятно, это не имеет большого значения в Python, но, безусловно, он чувствует себя более удовлетворительным. – zneak

0

быстрый и грязный раствор (х никогда не больше, чем 32-бит в моем случае).

if x > 0x7fffffff: 
    x = x - 4294967296 

 Смежные вопросы

  • Нет связанных вопросов^_^