A companion to IEEE 754 80-bit Extended double (long double) to 64-bit double unpack, this takes an IEEE 64-bit real (Perl NV) and packs into a 10-byte binary encoded IEEE 754 80-bit real.
Testing limited to Intel P4 and Perl 5.8.6/7 under WinXP.
Reinstated, as I believe it now correctly handles all cases.
(Be careful what you read on the internet. Not all reference material is created equal.)
sub IEEE64toIEEE80 { my( $mantissa, $exponent, $sign ) = unpack 'a52 a11 a1', unpack 'b64', pack 'd', $_[ 0 ]; return unpack 'd', pack 'b80', '0' x 79 . $sign unless $mantissa = +~ m[1] or $exponent =~ m[1]; if( $exponent !~ m[0] ) { $exponent = '111111111111111'; } else { $exponent = unpack( 'v', pack 'b11', $exponent ) - 1023; $exponent -= length( $1 ) if $exponent == -1023 and $mantissa +=~ m[(0+$)]; $exponent = unpack 'b15', pack 'v', $exponent + 16383; } return pack 'b80', '0'x 11 . $mantissa . '1' . $exponent . $sign; }
What Perl thinks it's writing and what D reads back for a selection of values at the boundaries:
c:\test>\test\to80bit.pl >junk.dat c:\test>readreal80 junk.da +t FFFFFFFFFFFFFFFF -1.#QNAN -nan FFF8000000000001 -1.#QNAN -nan FFF8000000000000 -1.#IND -nan FFF0000000000001 -1.#QNAN -nan FFF0000000000000 -1.#INF -inf FFEFFFFFFFFFFFFF -1.7976931348623157e+308 -1.797693134862315707900e+ +308 8010000000000000 -2.2250738585072014e-308 -2.225073858507201383200e- +308 800FFFFFFFFFFFFF -2.2250738585072009e-308 -2.225073858507201136000e- +308 8000000000000001 -4.9406564584124654e-324 -4.940656458412466538300e- +324 8000000000000000 0 0.0000000000000000000000 0000000000000000 0 0.0000000000000000000000 0000000000000001 4.9406564584124654e-324 4.940656458412466538300e- +324 000FFFFFFFFFFFFF 2.2250738585072009e-308 2.225073858507201136000e- +308 0010000000000000 2.2250738585072014e-308 2.225073858507201383200e- +308 7FEFFFFFFFFFFFFF 1.7976931348623157e+308 1.797693134862315707900e+ +308 7FF0000000000000 1.#INF inf 7FF0000000000001 1.#QNAN nan 7FF7FFFFFFFFFFFF 1.#QNAN nan 7FF8000000000000 1.#QNAN nan 7FFFFFFFFFFFFFFF 1.#QNAN nan
|
|---|