Как преобразовать float в hex
В Python мне нужно преобразовать кучу поплавков в шестнадцатеричный. Он должен быть заполнен нулями (например, 0x00000010 вместо 0x10). Так же, как http://gregstoll.dyndns.org/~gregstoll/floattohex/. (к сожалению, я не могу использовать внешние библиотеки на своей платформе, поэтому я не могу использовать тот, который представлен на этом веб-сайте)
Каков наиболее эффективный способ сделать это?
Ответы
Ответ 1
Это немного сложно в python, потому что они не хотят преобразовывать значение с плавающей запятой в целое число (hex). Вместо этого вы пытаетесь интерпретировать двоичное представление IEEE 754 значения с плавающей запятой как hex.
Мы будем использовать функции pack
и unpack
из встроенной библиотеки struct
.
A float
- 32 бит. Сначала мы скроем pack
в двоичную строку 1 а затем unpack
в качестве int
.
def float_to_hex(f):
return hex(struct.unpack('<I', struct.pack('<f', f))[0])
float_to_hex(17.5) # Output: '0x418c0000'
Мы можем сделать то же самое для double
, зная, что это 64 бита:
def double_to_hex(f):
return hex(struct.unpack('<Q', struct.pack('<d', f))[0])
double_to_hex(17.5) # Output: '0x4031800000000000L'
1 - значение строки необработанных байтов; не строка из них и нули.
Ответ 2
В Python float
всегда выполняется двойная точность.
Если вам требуется, чтобы ваш ответ выводился в виде шестнадцатеричного целого числа, вопрос уже был отвечен:
import struct
# define double_to_hex as in the other answer
double_to_hex(17.5) # Output: '0x4031800000000000'
double_to_hex(-17.5) # Output: '0xc031800000000000'
Однако вместо этого вы можете использовать встроенную функцию:
(17.5).hex() # Output: '0x1.1800000000000p+4'
(-17.5).hex() # Output: '-0x1.1800000000000p+4'
# 0x1.18p+4 == (1 + 1./0x10 + 8./0x100) * 2**4 == 1.09375 * 16 == 17.5
Это тот же ответ, что и раньше, только в более структурированном и удобочитаемом формате.
Нижние 52 бита - мантисса. Верхние 12 бит состоят из знакового бита и 11-битного показателя; смещение экспоненты составляет 1023 == 0x3FF, поэтому 0x403 означает "4". См. Статья в Википедии о плавающей запятой IEEE.
Ответ 3
В дополнение к очень полезному ответу Джонатона Рейнхарта. Мне нужно было это, чтобы отправить число с плавающей запятой в байтах по UDP
import struct
# define double_to_hex (or float_to_hex)
def double_to_hex(f):
return hex(struct.unpack('<Q', struct.pack('<d', f))[0])
# On the UDP transmission side
doubleAsHex = double_to_hex(17.5)
doubleAsBytes = bytearray.fromhex(doubleAsHex.lstrip('0x').rstrip('L'))
# On the UDP receiving side
doubleFromBytes = struct.unpack('>d', doubleAsBytes)[0] # or '>f' for float_to_hex
Ответ 4
если вы находитесь на микропитоне (который не указан в вопросе, но у меня возникли проблемы с поиском), вы можете использовать это
import binascii
def float_to_hex(f):
binascii.hexlify(struct.pack('<f', f))
float_to_hex(17.5) #Answer: 0x418c0000