IBM 32-bit Floating Point Conversion

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • magoo

    IBM 32-bit Floating Point Conversion

    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:


    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 = "11000010101100 011001111110101 111")
    # (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_str ing, 0, 1);
    if ( $first_digit eq "0" ) {
    $sign_bit = 1;
    } elsif ( $first_digit eq "1" ) {
    $sign_bit = -1;
    }

    $bin_exponent = substr($bit_str ing, 1, 7);
    $exponent = bin2dec($bin_ex ponent);

    #============== =============== =============== =============== ==========
    #Computing fraction
    #The following will do this:
    # take last 24 bits of $bit_string such as "10110001100111 1110101111"
    # 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_str ing, 8, 24);
    @bit_chars = unpack("A1" x length($bin_fra ction), $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
Working...