Help need with converting Hex string to IEEE format float

Discussion in 'Python' started by i_vincent@hotmail.com, Dec 14, 2004.

  1. Guest

    Hi all,

    Newbie Python programmer here, so please be patient. I have spent all
    day googling for an answer to my problem, but everything I try fails to
    work (or works from the Interpreter with a set value but not from my
    code with dynamic values).

    Okay, here is the general gist of the problem. I am using Python to
    parse an output file (from a MAK Logger but that is not really
    important). Now I have some data that is contained on a line in this
    file like:

    80 00 00 00

    Each of these numbers is a Hex byte making up a four byte (32 bit
    Big-Endian) IEEE float. I have read this data into Python using
    readlines and then line.split(). This gives me:

    ['80', '00', '00', '00']

    I am then reading these in as:

    wib[0] + wib[1] + wib[2] + wib[3] = 8000000 as a string

    Now this is the point where I get stuck, I have tried various ways of
    implementing the pack/unpack methods of the struct module but with no
    luck.

    One example I tried was:

    wibble = struct.unpack("f", struct.pack("l", long(conv_str, 16)))
    OverflowError: long int too large to convert to int

    If I follow the examples I have found on the net using a set value of
    0x80000000 in them, everything works fine from the interpreter line.

    Arrrggggghhhh.

    Everything has worked really easily up this point but I am now stuck
    completely, I would be grateful for any help people can offer.
    Regards

    Ian Vincent
     
    , Dec 14, 2004
    #1
    1. Advertising

  2. <> wrote:

    > Newbie Python programmer here, so please be patient. I have spent all
    > day googling for an answer to my problem, but everything I try fails to
    > work (or works from the Interpreter with a set value but not from my
    > code with dynamic values).
    >
    > Okay, here is the general gist of the problem. I am using Python to
    > parse an output file (from a MAK Logger but that is not really
    > important). Now I have some data that is contained on a line in this
    > file like:
    >
    > 80 00 00 00
    >
    > Each of these numbers is a Hex byte making up a four byte (32 bit
    > Big-Endian) IEEE float. I have read this data into Python using
    > readlines and then line.split(). This gives me:
    >
    > ['80', '00', '00', '00']


    how about:

    # convert to byte string
    import struct
    s = "".join([chr(int(c, 16)) for c in x])
    v = struct.unpack("!f", s)

    or

    # convert to byte string, via the array module
    import array, struct
    a = array.array("B", [int(c, 16) for c in x])
    v = struct.unpack("!f", )

    </F>
     
    Fredrik Lundh, Dec 14, 2004
    #2
    1. Advertising

  3. > # convert to byte string, via the array module
    > import array, struct
    > a = array.array("B", [int(c, 16) for c in x])
    > v = struct.unpack("!f", )


    eh? should be:

    # convert to byte string, via the array module
    import array, struct
    a = array.array("B", [int(c, 16) for c in x])
    v = struct.unpack("!f", a)

    </F>
     
    Fredrik Lundh, Dec 14, 2004
    #3
  4. Max M Guest

    wrote:

    > Each of these numbers is a Hex byte making up a four byte (32 bit
    > Big-Endian) IEEE float. I have read this data into Python using
    > readlines and then line.split(). This gives me:
    >
    > ['80', '00', '00', '00']



    Oh, programmers loves this kind stuff. You should get tons of answers.

    ##
    st = '80 00 00 00'

    import binascii
    import struct

    s = ''.join([binascii.a2b_hex(s) for s in st.split()])
    v = struct.unpack("f", s)[0]
    print v
    ##

    regards Max M

    --

    hilsen/regards Max M, Denmark

    http://www.mxm.dk/
    IT's Mad Science
     
    Max M, Dec 14, 2004
    #4
  5. Max M wrote:

    > Oh, programmers loves this kind stuff. You should get tons of answers.


    data = '80 00 00 00'

    import Image
    v = Image.fromstring("F", (1, 1), data, "hex", "F;32BF").getpixel((0, 0))

    </F>
     
    Fredrik Lundh, Dec 14, 2004
    #5
  6. On Tue, 14 Dec 2004 16:57:02 +0100, rumours say that "Fredrik Lundh"
    <> might have written:

    >how about:
    >
    > # convert to byte string
    > import struct
    > s = "".join([chr(int(c, 16)) for c in x])
    > v = struct.unpack("!f", s)


    I think that the third line in the snippet above could also be:

    s = "".join(x).decode("hex")

    I am not sure I remember in which version of Python the hex codec was
    added, but it is handy.
    --
    TZOTZIOY, I speak England very best.
    "Be strict when sending and tolerant when receiving." (from RFC1958)
    I really should keep that in mind when talking with people, actually...
     
    Christos TZOTZIOY Georgiou, Dec 15, 2004
    #6
  7. Peter Hansen Guest

    Christos TZOTZIOY Georgiou wrote:
    > s = "".join(x).decode("hex")
    >
    > I am not sure I remember in which version of Python the hex codec was
    > added, but it is handy.


    Of course, binascii could do this since 2.0 or so, but not
    having to import another module *is* nice:

    >>> 'ff12'.decode('hex')

    '\xff\x12'

    >>> import binascii
    >>> binascii.unhexlify('ff12')

    '\xff\x12'

    Thanks for pointing it out, Christos.
     
    Peter Hansen, Dec 15, 2004
    #7
  8. <> wrote in message
    news:...

    > One example I tried was:
    >
    > wibble = struct.unpack("f", struct.pack("l", long(conv_str, 16)))
    > OverflowError: long int too large to convert to int


    You can't fit 0x80000000L into a signed 32-bit integer, use 'L' for
    an unsigned one.

    > If I follow the examples I have found on the net using a set value of
    > 0x80000000 in them, everything works fine from the interpreter line.


    This depends on the Python version: before 2.4 0x80000000
    corresponds to the bit pattern you expect but will be negative.
    That's why it's happy as a signed 32-bit integer.

    >>> 0x80000000 == 0x80000000L

    <interactive input>:1: FutureWarning: hex/oct constants > sys.maxint
    will return positive values in Python 2.4 and up
    ....
    False
     
    Richard Brodie, Dec 16, 2004
    #8
  9. Ian Vincent Guest

    Max M <> wrote in news:41bf121e$0$280
    $:
    >
    > ##
    > st = '80 00 00 00'
    >
    > import binascii
    > import struct
    >
    > s = ''.join([binascii.a2b_hex(s) for s in st.split()])
    > v = struct.unpack("f", s)[0]
    > print v
    > ##


    This one worked great for what I was trying to do.

    Thanks to everybody for your help.

    TTFN

    Ian
     
    Ian Vincent, Dec 17, 2004
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andy
    Replies:
    7
    Views:
    6,266
    Roedy Green
    May 10, 2004
  2. Replies:
    10
    Views:
    6,220
    Neredbojias
    Aug 19, 2005
  3. bd
    Replies:
    0
    Views:
    634
  4. Bengt Richter
    Replies:
    6
    Views:
    473
    Juha Autero
    Aug 19, 2003
  5. Carsten Fuchs
    Replies:
    45
    Views:
    1,555
    James Kanze
    Oct 8, 2009
Loading...

Share This Page