#! perl -slw use strict; sub real8ToDouble { my( $real8 ) = shift; my $bits = reverse unpack 'b64', $real8; # IEEE 754 64-bit real (double) format # seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff #1-sign 11- mantissa 52-bits (+1 implicit) binary fraction my( $sign, $exp, $frac ) = $bits =~ m[(.)(.{11})(.{52})]; my $expAsInt = unpack( 'v', pack 'b16', scalar reverse $exp ) - 1023; my $f = 1; my $n = 1; for my $bp ( split '', $frac ) { $n /= 2; $f += $n if $bp; } return ( $f * 2**$expAsInt ) * ( $sign ? -1 : 1 ); } for ( 1 .. 20 ) { my( $s, $c, $m ) = ( rand > 0.5 ? '+' : '-', rand, int( rand 600 ) -300 ); my $double = "$s${c}E$m"; printf "%g : %g\n", $double, real8ToDouble( pack 'd', $double ); } __END__ P:\test>452186.pl -3.27454e+126 : -3.27454e+126 -6.33606e-135 : -6.33606e-135 -9.78943e-089 : -9.78943e-089 3.75458e-262 : 3.75458e-262 9.11469e-049 : 9.11469e-049 6.66809e-052 : 6.66809e-052 9.58191e+086 : 9.58191e+086 -7.59277e+284 : -7.59277e+284 3.93188e-021 : 3.93188e-021 -4.28009e-048 : -4.28009e-048 -5.32776e-173 : -5.32776e-173 5.55817e-147 : 5.55817e-147 -4.44031e+060 : -4.44031e+060 2.40295e+126 : 2.40295e+126 8.55194e+132 : 8.55194e+132 5.61005e+184 : 5.61005e+184 -9.57489e-107 : -9.57489e-107 8.71338e+130 : 8.71338e+130 5.66986e+227 : 5.66986e+227 3.41461e-116 : 3.41461e-116