Чтение 32-битного значения со знаком из «беззнакового» потока - PullRequest
4 голосов
/ 09 февраля 2012

Я хочу извлечь данные из файла, чья информация хранится в формате с прямым порядком байтов, а всегда без знака.Как "cast" из unsigned int в int влияет на фактическое десятичное значение?Правильно ли я, что самый левый бит решает, является ли значение положительным или отрицательным?

Я хочу проанализировать этот формат файла с помощью python, и значение чтения и без знака легко:

def toU32(bits):
    return ord(bits[0]) << 24 | ord(bits[1]) << 16 | ord(bits[2]) << 8  | ord(bits[3])

но как будет выглядеть соответствующая функция toS32 ?


Спасибо за информацию о struct -модуле.Но я все еще заинтересован в решении моего актуального вопроса.

Ответы [ 3 ]

8 голосов
/ 09 февраля 2012

Я бы использовал struct .

import struct

def toU32(bits):
    return struct.unpack_from(">I", bits)[0]

def toS32(bits):
    return struct.unpack_from(">i", bits)[0]

Строка формата "> I" означает чтение с прямым порядком байтов ">", целое число без знака, "I", избиты строки.Для целых чисел со знаком вы можете использовать "> i".

РЕДАКТИРОВАТЬ

Пришлось посмотреть на другой StackOverflow ответ , чтобы вспомнить, как "конвертировать"целое число со знаком из целого числа без знака в python.Хотя это не столько преобразование, сколько переосмысление битов.

import struct

def toU32(bits):
        return ord(bits[0]) << 24 | ord(bits[1]) << 16 | ord(bits[2]) << 8  | ord(bits[3])

def toS32(bits):
    candidate = toU32(bits);
    if (candidate >> 31): # is the sign bit set?
        return (-0x80000000 + (candidate & 0x7fffffff)) # "cast" it to signed
    return candidate


for x in range(-5,5):
    bits = struct.pack(">i", x)
    print toU32(bits)
    print toS32(bits)
0 голосов
/ 22 марта 2014

Безусловная версия toS32 (биты) может выглядеть примерно так:

def toS32(bits):
    decoded = toU32(bits)
    return -(decoded & 0x80000000) + (decoded & 0x7fffffff)

Конечно, вы можете заранее вычислить маску для любого другого размера в битах.

0 голосов
/ 09 февраля 2012

Я бы использовал struct pack *1002* методы модуля pack и unpack.

См. Порядковые числа чисел в Python для некоторых примеров.

...