[Pdx-pm] PowerPC and little-endian
Marvin Humphrey
marvin at rectangular.com
Wed Mar 1 10:06:11 PST 2006
On Feb 28, 2006, at 6:37 PM, Eric Wilhelm wrote:
> I need to unpack some floats and doubles in a cross-platform way
I gather that since you're considering recompiling Perl, this doesn't
have to work on esoteric platforms. So long as all the boxes that
you need to run this on use IEEE 754 for floats and doubles, it
wouldn't be that hard to write your own serialization routines using
Inline C.
Here's a demo script that illustrates the principle with floats:
#!/usr/bin/perl
use strict;
use warnings;
use Config;
use Inline C => <<'END_C';
SV*
serialize_float(float f) {
SV *serialized_sv;
unsigned char *buf;
I32 bits;
/* allocate a scalar to hold the serialized output */
serialized_sv = newSV(5);
SvPOK_on(serialized_sv);
SvCUR_set(serialized_sv, 4);
buf = (unsigned char*)SvPVX(serialized_sv);
/* copy the bits from the float into a 32-bit integer vessel */
bits = *(I32*)&f;
/* encode "bits" in big-endian byte-order */
*buf++ = (bits & 0xff000000) >> 24;
*buf++ = (bits & 0x00ff0000) >> 16;
*buf++ = (bits & 0x0000ff00) >> 8;
*buf++ = (bits & 0x000000ff);
/* null terminate the scalar's string */
*buf = '\0';
return serialized_sv;
}
END_C
print "Byte order: $Config{byteorder}\n";
for ( 0, 1, 1.3, 2, 10, 9999, -1, -9999 ) {
my $float_string = serialize_float($_);
print unpack( 'B*', $float_string ) . "\n";
}
Output from a G4 laptop running OS X 10.4.5 and from a Pentium 4
running FreeBSD 5.3 is appended below.
So long as you write up some tests to make sure the serialization
schemes produce the output you expect, you should be safe.
Here's links for a few web pages that address the issue of cross-
platform-compatible serialization of floating point formats:
http://www.bookofhook.com/poshlib/Overview.html
http://www.codeproject.com/tools/libnumber.asp
http://www.python.org/peps/pep-0754.html
http://babbage.cs.qc.edu/IEEE-754/IEEE-754references.html
Marvin Humphrey
Rectangular Research
http://www.rectangular.com/
#--------------------------------------------
# G4:
Byte order: 4321
00000000000000000000000000000000
00111111100000000000000000000000
00111111101001100110011001100110
01000000000000000000000000000000
01000001001000000000000000000000
01000110000111000011110000000000
10111111100000000000000000000000
11000110000111000011110000000000
#--------------------------------------------
# Pentium 4:
Byte order: 12345678
00000000000000000000000000000000
00111111100000000000000000000000
00111111101001100110011001100110
01000000000000000000000000000000
01000001001000000000000000000000
01000110000111000011110000000000
10111111100000000000000000000000
11000110000111000011110000000000
More information about the Pdx-pm-list
mailing list