How to convert a float into hex

后端 未结 4 1481
情话喂你
情话喂你 2020-12-02 21:02

In Python I need to convert a bunch of floats into hexadecimal. It needs to be zero padded (for instance, 0x00000010 instead of 0x10). Just like http://gregstoll.dyndns.org/

相关标签:
4条回答
  • 2020-12-02 21:32

    if you are on micropython (which is not said in the question, but I had trouble finding) you can use this

    import struct
    import binascii
    def float_to_hex(f):
        binascii.hexlify(struct.pack('<f', f))
    float_to_hex(17.5) # 0x418c0000
    
    0 讨论(0)
  • 2020-12-02 21:33

    This is a bit tricky in python, because aren't looking to convert the floating-point value to a (hex) integer. Instead, you're trying to interpret the IEEE 754 binary representation of the floating-point value as hex.

    We'll use the pack and unpack functions from the built-in struct library.

    A float is 32-bits. We'll first pack it into a binary1 string, and then unpack it as an int.

    def float_to_hex(f):
        return hex(struct.unpack('<I', struct.pack('<f', f))[0])
    
    float_to_hex(17.5)    # Output: '0x418c0000'
    

    We can do the same for double, knowing that it is 64 bits:

    def double_to_hex(f):
        return hex(struct.unpack('<Q', struct.pack('<d', f))[0])
    
    double_to_hex(17.5)   # Output: '0x4031800000000000L'
    

    1 - Meaning a string of raw bytes; not a string of ones and zeroes.

    0 讨论(0)
  • 2020-12-02 21:37

    In Python float is always double-precision.

    If you require your answer to be output in the form of a hexadecimal integer, the question was already answered:

    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'
    

    However you might instead consider using the builtin function:

    (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
    

    This is the same answer as before, just in a more structured and human-readable format.

    The lower 52 bits are the mantissa. The upper 12 bits consists of a sign bit and an 11-bit exponent; the exponent bias is 1023 == 0x3FF, so 0x403 means '4'. See Wikipedia article on IEEE floating point.

    0 讨论(0)
  • 2020-12-02 21:55

    Further to Jonathon Reinhart's very helpful answer. I needed this to send a floating point number as bytes over 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
    
    0 讨论(0)
提交回复
热议问题