Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Python > IEEE-754 hex -> float


Автор: bur80 09.06.19, 04:27
Есть число 0x471b4ac2 представленное в IEEE-754, которое необходимо преобразовать в число с плавающей точкой (float).

В сети нашёл конвертер, который выполняет данную операцию и преобразует 0x471b4ac2 в 39754.758.

Прошу помочь с алгоритмом для Python :wall:

Нашёл преобразование float -> bin:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    import struct
     
    getBin = lambda x: x > 0 and str(bin(x))[2:] or "-" + str(bin(x))[3:]
     
    def float2bin32(value):
    #    val = struct.unpack('Q', struct.pack('d', value))[0] # 64
        val = struct.unpack('I', struct.pack('f', value))[0] # 32
        return getBin(val)


Мне же требуется обратное преобразование, то есть bin -> float

С преобразованием bin -> hex и обратно затруднений не имеется :)

Автор: bur80 09.06.19, 05:44
знаний математики хватило, чтобы разобраться в алгоритме самостоятельно. Очень помог параграф 4 отсюда.

Ниже моя реализация. Сделал как умею, так что за изящность кода прошу не пинать.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    def hex2bin(hx): # IEEE-754 32 -> bin
        bn = bin(int(hx, 16))[2:]
        return bn
     
    def bin2dec(bn): # IEEE-754 32 -> float
        if len(bn) == 31:
            s = 0
            e = bn[0:8]
            m = bn[8:]
        else:
            s = 1
            e = bn[1:8]
            m = bn[9:]
        f = (-1)**s*2**(int(e,2)-127)*(1+int(m,2)/2**23)
        return f

:whistle:

Автор: amk 09.06.19, 07:16
Можно было воспользоваться тем же модулем struct. Там наряду с unpack есть функция с противоположным действием - pack.

Автор: bur80 09.06.19, 07:36
Цитата amk @
Можно было воспользоваться тем же модулем struct. Там наряду с unpack есть функция с противоположным действием - pack.

пример, пожалуйста!

Автор: amk 09.06.19, 08:06
Цитата bur80 @
пример, пожалуйста!
Английский не понимаешь? В справке всё написано.

struct.pack('f', 39754.758)
преобразует число с плавающей точкой в последовательность байт b'\xc2J\x1bG' == bytes(194, 74, 27, 71)

int.from_bytes(b'\xc2J\x1bG', byteorder='little')
преобразует полученную последовательность в целое число 1192970946 == 0x471b4ac2

Последнее преобразование можно выполнить с использованием модуля struct
struct.unpack('i', b'\xc2J\x1bG')[0]

Или в одну строку

int.from_bytes(struct.pack('f', 39754.758), byteorder='little')
struct.unpack('i', struct.pack('f', 39754.758))[0]

Последняя строка отличается от строки в твоём первом посте только расположением форматов 'i' и 'f' (!).

Автор: piksel 10.06.19, 04:00
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    import struct
    print(struct.unpack('!f', bytes.fromhex('{:x}'.format(orig)))[0])

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)