I have data that includes 80-bit floating point numbers. The application that generates the data was written in 1994 to run on Macintosh, using an unknown development environment. My desire was to be able to extract the value as a Perl NV, and, eventually, to be able to go the other way. Thanks to BrowserUK's snippet, and some other digging, I've gotten the conversion working from 80-bit to Perl NV.

This snippet expects to find the bytes in big-endian order, such as on a PowerPC. Much probing via unpack 'b80',... and the like were needed to get myself more fully educated on how the bits were actually laid out.

This version cribs liberally from BrowserUK's snippet.

It's been lightly tested on a G4 PPC. I don't have a way to generate arbitrary 80-bit values, and my source only generates a limited range that runs in the 0..100 or less range.

Update: further testing lead to changes and some simplifications...

With that, the code:

sub IEEE80toIEEE64 { my $ieee80 = shift; # reverse the byte order; this makes it look like an Intel 80-bit +doohickey my $ieee80r = join('', reverse(split //, unpack 'a10', $ieee80)); # now pick it apart my( $discard, $mantissa, $hidden, $exponent, $sign ) = unpack 'a11 a52 a1 a15 a1', unpack 'b80', $ieee80r; # readjust the exponent $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; # put it back together my $ieee64r = join('', $mantissa, $exponent, $sign); # reverse the byte order back to Motorola-normal my $ieee64 = join('', reverse(split //, unpack 'a8', pack 'b64', $ +ieee64r)); # ...and convert the binary to a Perl NV return unpack 'd', $ieee64; }
  • Comment on IEEE 754 80-bit extended double precision to IEEE 754 64-bit double-precision
  • Download Code