RE: floating point convertion

From: Charles K. Clarkson (cclarkson_at_htcomp.net)
Date: 08/05/04


To: "'Mark Cohen'" <m.cohen@tiscalinet.it>, <beginners@perl.org>
Date: Thu, 5 Aug 2004 10:47:25 -0500

From: Mark Cohen <mailto:m.cohen@tiscalinet.it> wrote:

: Hello ,
:
: I have a transferred a file from an IBM mainframe
: to a windows platform that I need to analyse. The
: file contains an 8 byte floating point hexadecimal
: representaion 44FE880000000000.
:
: This should be converted to the number 65160.

    When I use this sub I get 1.21711040165713e-008
not 65160.

print floatmvs( '44FE880000000000' );

: sub floatmvs {
: my $mat=0;
: my $firstbyte = unpack "H2", $_[0];
: my $exp=$firstbyte-40; # base 16
: my $bin=unpack('B*',substr($_[0],1,7));
: for ($start=0; $start <56; $start+=1) {
: $bit=substr($bin,$start,1);
: $bitpos=$start+1;
: if ($bit == 1) {
: $val=(1/2)**($bitpos);
: $mat=$mat+$val;
: }
: }
: my $num=$mat*(16**$exp);
: return $num;
: }

    With 'strict' and 'warnings' turned on, I get
the same result with this.

use strict;
use warnings;

print floatmvs2( '44FE880000000000' );

sub floatmvs2 {
    my @bits = split //, unpack 'B*', substr( $_[0], 1, 7 );

    my $mat = 0;
    foreach my $pos ( 0 .. $#bits ) {
        $mat += $bits[ $pos ] * ( 1 / 2 ) ** ( $pos + 1 );
    }

    my $exp = unpack( 'H2', $_[0] ) - 40;
    return $mat * ( 16 ** $exp );
}

HTH,

Charles K. Clarkson

-- 
Mobile Homes Specialist
254 968-8328