This accepts a 10-byte binary encoded IEEE 754 80-bit real and unpacks it into a IEEE 64-bit real (Perl NV).

Testing is limited to Intel P4 (Does anyone else do 80-bit FP math?) and Perl 5.8.6/7 under WinXP.

The test data below shows a selected range of values and compares the output from the generating program's vprintf equivalent, and Perl's printf on the converted results. The values are selected to highlight the range and accuracy limitations of both formats at all four! ends of the scale.

It shows correct handling of underflow and overflow by conversion to [+|-]1.#INF as appropriate.

I believe it will handle #NaN (& #QNaN) correctly, but this has not been tested, as I haven't worked out how to generate these in the writer.

A version that doesn't go through ASCII encoded binary has so far eluded me due to the limitations of 32-bit integers for the bit twiddling.

Copyright (©) 2006. BrowserUk (BrowserUk -> cpan org).
sub IEEE80toIEEE64 { my( $discard, $mantissa, $hidden, $exponent, $sign ) = unpack 'a11 a52 a1 a15 a1', unpack 'b80', $_[ 0 ]; $exponent = unpack( 'v', pack 'b15', $exponent ) - 16383 + 1023; $exponent = 32767, $mantissa = '0' x 52 if $exponent < 0 or $exponent > 2047; $exponent = unpack 'b11', pack 'v', $exponent; return unpack 'd', pack 'b64', $mantissa . $exponent . $sign; }
realtest x.bin C:\dmd\test>\test\80bit.pl -1.0935598595647423806e-4950 -1.#INF 1.0935598595647423806e-4950 1.#INF -1.2345678901234567887e-4932 -1.#INF 1.2345678901234567887e-4932 1.#INF -1.2345678901234567887e-309 -1.#INF 1.2345678901234567887e-309 1.#INF -1.2345678901234567912e-206 -1.2345678901234567e-206 1.2345678901234567912e-206 1.2345678901234567e-206 -1.2345678901234567937e-103 -1.2345678901234568e-103 1.2345678901234567937e-103 1.2345678901234568e-103 -1.234567890123456796 -1.2345678901234567 1.234567890123456796 1.2345678901234567 -1.2345678901234567983e+103 -1.2345678901234567e+103 1.2345678901234567983e+103 1.2345678901234567e+103 -1.2345678901234568006e+206 -1.2345678901234568e+206 1.2345678901234568006e+206 1.2345678901234568e+206 -1.2345678901234568031e+309 -1.#INF 1.2345678901234568031e+309 1.#INF -1.2345678901234567889e+4930 -1.#INF 1.2345678901234567889e+4930 1.#INF -1.2345678901234567892e+4931 -1.#INF 1.2345678901234567892e+4931 1.#INF 0.005000 0.0049999999999999992 -0.005000 -0.0049999999999999992 0.050000 0.049999999999999996 -0.050000 -0.049999999999999996 0.500000 0.5 -0.500000 -0.5 5.000000 5 -5.000000 -5 50.000000 50 -50.000000 -50

In reply to IEEE 754 80-bit Extended double (long double) to 64-bit double unpack by BrowserUk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.