herveus has asked for the wisdom of the Perl Monks concerning the following question:

Howdy!

I'm reverse-engineering a file format. The binary data includes some 80-bit floats -- "extended double precision". pack/unpack don't handle these.

I've tried searching using Google, and I've tried to discover something on CPAN. So far, I've found nothing that helps.

Does anyone know of a module to provide the pack/unpack functionality for this data type?

Thanks.

Update: I've got the important part done, based liberally on BrowserUK's snippet. Thanks to all for the help.

yours,
Michael
  • Comment on Unpacking extended-double precision floats

Replies are listed 'Best First'.
Re: Unpacking extended-double precision floats
by samtregar (Abbot) on Nov 29, 2006 at 17:43 UTC
    Have you looked at Convert::Binary::C? If it doesn't support your floating-point format perhaps you can add support for it. It seems like a pretty flexible module.

    -sam

      Howdy!

      I had not discovered that module. I'm calling it up as I write this.

      ...

      That might do the trick. I'll try it and see. Thanks!

      yours,
      Michael
Re: Unpacking extended-double precision floats
by ikegami (Patriarch) on Nov 29, 2006 at 18:18 UTC

    If your Perl supports extended double precision floats natively, then you can unpack them using the D pack code. Quoting pack's documentation, D is used to pack/unpack the following:

    A long double-precision float in the native format. (Long doubles are available only if your system supports long double values _and_ if Perl has been compiled to support those. Causes a fatal error otherwise.)

    Otherwise, I'm curious as to what you're expecting to get. Are you expecting a double, a string or a Math::BigFloat?

    If you can read those floats in C, one solution would be to write a conversion routine in C and call it via XS or Inline::C.

      Howdy!

      I'm reading a binary file. Part of the file consists of 10-byte sequences that are clearly floats, probably IEEE extended-double-precision floats. I'm looking to be able to convert to unpack that to a numeric value and pack it to a 10-byte sequence.

      That is, unpack 0x4001c888888888888888 to 12.5 (if I'm remembering actual data correctly), and pack 12.5 back to 0x4001c888888888888888.

      I may just resort to picking the bits apart and converting it myself. I'm not sure if my C compiler (gcc on Mac) does that particular datatype. I can afford to simply do the bit-slinging myself, if it comes to that. I was just hoping to find that someone else has already solved the problem. So far, no joy.

      update: added more words to clarify

      yours,
      Michael

        My question was about 12.5's format. You implied (in a private message) that the lost of precision is of no concern, so I'm deducing that you want an NV (double).

        Have you tried unpack 'D' yet?

Re: Unpacking extended-double precision floats
by Fengor (Pilgrim) on Nov 29, 2006 at 18:10 UTC
    I have found a site about floating points on pentium chips which lists a mantissa of 64 bits for extended double precision which would leave 15 bits for the exponent and 1 for the sign bit. maybe that helps you in reading it.

    --
    "WHAT CAN THE HARVEST HOPE FOR IF NOT THE CARE OF THE REAPER MAN"
    -- Terry Pratchett, "Reaper Man"

      Howdy!

      That's a minimum size implementation of the format. If I have to do it myself, I'll be referring to that.

      yours,
      Michael
Re: Unpacking extended-double precision floats
by Fengor (Pilgrim) on Nov 29, 2006 at 17:39 UTC
    A quick google turned this up for double precison format dunno about extended though
    Floating point Numbers

    For packing floating point numbers you have the choice between the pack codes f and d which pack into (or unpack from) single-precision or double-precision representation as it is provided by your system. (There is no such thing as a network representation for reals, so if you want to send your real numbers across computer boundaries, you'd better stick to ASCII representation, unless you're absolutely sure what's on the other end of the line.)
    from pack

    --
    "WHAT CAN THE HARVEST HOPE FOR IF NOT THE CARE OF THE REAPER MAN"
    -- Terry Pratchett, "Reaper Man"

      Howdy!

      Thanks for trying (and no, I'm not being snarky). That doesn't quite cover my situation.

      f is a 32-bit "single-precision" float.

      d is a 64-bit "double-precision" float.

      I'm dealing with 80-bit "extended-double-precision" floats.

      yours,
      Michael
        yeah after looking a bit deeper into it i figured as much. Hmm maybe since pack converts into double-precision representation as it is provided by your system it would be possible to fool perl into believing double precision would take 80 bytes instead of 64?

        I'm reading through the POD of the Config Module as i write this and found the variables d_dbl_digit and d_ldbl_digit to be interesting. but it seems the Config module only supplies readonly access to those variables :/

        --
        "WHAT CAN THE HARVEST HOPE FOR IF NOT THE CARE OF THE REAPER MAN"
        -- Terry Pratchett, "Reaper Man"

Re: Unpacking extended-double precision floats
by BrowserUk (Patriarch) on Nov 30, 2006 at 13:04 UTC

    See IEEE 754 80-bit Extended double (long double) to 64-bit double unpack for a possible solution; provided that your data was written in Intel and you are reading it back on Intel.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Howdy!

      I'm working on a Motorola CPU, but this may be just the ticket. If it works for 80->64, I'll see about inverting it as well. An Intel "extended double" is a valid form of IEEE754 extended-double-precision, which requires at least 80 bits to hold it. The 128 bit "long double" that Sun uses is another conforming implementation, as that standard simply sets minimum bit sizes for exponent and mantissa.

      Thanks!

      yours,
      Michael