Velocity Reviews > Perl > IBM 32-bit Floating Point Conversion

IBM 32-bit Floating Point Conversion

magoo
Guest
Posts: n/a

 05-03-2004
Gentlemen,

Recently I had need to roll my own conversion routine for reading data
values from a SEGY file (seismic data values) which were in IBM 32-bit
floating point format.

I would like to post my routine in the hopes of perhaps helping someone
else and/or getting feedback on what someone else has done along these
lines.

I was greatly helped by the following article:
http://www.sis.slb.com/content/servi...2_n6_2003i.asp

which can be found by searching Google for:
"what is the difference between ibm 32 bit floating point and ieee"

Step 1: Get a data value from file

\$bit_string = unpack("B*", \$trace_sample);

Step 2: Convert bits which are in IBM 32-bit floating point value

\$trace_value = conv_bit_string_2_ibm32float(\$bit_string);

#================================================= =====================
#copied from "Perl Cookbook, recipe 2.4
sub bin2dec {
return unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
}
#================================================= ======================
#================================================= ======================
sub conv_bit_string_2_ibm32float {
\$bit_string = shift;

#================================================= ============
#DEBUG (make \$bit_string = "11000010101100011001111110101111")
# (1st bit, sign bit = 1 (denotes negative number))
# (next seven bits, exponent = 66)
# (last 24 bits represent fraction = 0.69384283 in decimal)
# (whole bit string as IBM 32 bit FP = -177.62376 decimal)
#================================================= ============

# A value of 1 for sign bit denotes a negative number
# while a value of zero denotes a positive number
#================================================= ===
\$first_digit = substr(\$bit_string, 0, 1);
if ( \$first_digit eq "0" ) {
\$sign_bit = 1;
} elsif ( \$first_digit eq "1" ) {
\$sign_bit = -1;
}

\$bin_exponent = substr(\$bit_string, 1, 7);
\$exponent = bin2dec(\$bin_exponent);

#================================================= ====================
#Computing fraction
#The following will do this:
# take last 24 bits of \$bit_string such as "101100011001111110101111"
# for each bit starting from left to right, convert to decimal
# i.e. (1 * 2**-1) + (0 * 2**-2) + (1 * 2**-3) + (1 * 2**-4) ...
#================================================= ====================
\$bin_fraction = substr(\$bit_string, 8, 24);
@bit_chars = unpack("A1" x length(\$bin_fraction), \$bin_fraction);

\$place_holder = -1;
\$fraction = 0;
foreach \$bit ( @bit_chars ) {
\$fraction += \$bit * (2 ** \$place_holder);
\$place_holder += -1;
}

\$ibm_float = (\$sign_bit ** 1) * (16 ** (\$exponent - 64)) *
(\$fraction);
return sprintf("%.10f", \$ibm_float);
}
#================================================= ======================

Regards,
Terry Michaels