IBM 32-bit Floating Point Conversion

M

magoo

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/services/client/theclick/v2_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

READ(IF, $trace_sample, 4)
$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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top