in reply to Extracting IEEE 754 floating point numbers


Unless you have esoteric hardware your platform probably supports IEEE754 floats.

The most probable cause of incompatibility is that the MS platform uses a little-endian byte order and your other platform uses a big-endian byte order. Try the following code on both platforms and compare the output:

my $num = 1.2345; print join(" ", map { sprintf "0x%02x", $_ } unpack("C*", pack "f", $num)), "\n";
If one is the reverse of the other you can use the following to unpack the float:     my $num = unpack "f", reverse $packed_num;

One other thing to look out for is that the floating point number might be packed as a 8-byte double and not as a 4-byte float.

Finally, as a *last* resort (because I think your problem is elsewhere) here is a function to portably unpack a 4-byte IEEE754 float in little-endian order. This is a port of a C function by Steve Summit from the book "C Unleashed":

use POSIX 'ldexp'; sub unpack_f_ieee754 { my @buf = unpack "C4", $_[0]; my $mant; my $num; $mant = $buf[0]; $mant |= $buf[1] << 8; $mant |= ($buf[2] & 0x7f) << 16; my $exp = (($buf[3] & 0x7f) << 1) | (($buf[2] >> 7) & 0x01); my $sign = $buf[3] & 0x80; if ($exp == 0) { $num = ldexp($mant, -126 -23); } else { # restore implicit leading $mant |= 1 << 23; $num = ldexp($mant, $exp -127 -23); } $num = -$num if $sign; return $num; }

--
John.