Mark Cohen <[EMAIL PROTECTED]> wrote:

: Hello Charles,
: I don't understand why you are getting differnet
: results. I checked approximatley 1000 records
: containing different floating points and it seems
: that the result is similar to the results I'm
: getting from SAS but I'll try to understand why
: this happens. I have a member that is required
: from the main program which uses this statement:
: 
: $R723CCPU=&floatmvs(substr($_record,$offsec+32,8));

    Well, it looks like you are passing a 8
characters long argument here, while the example
you gave has 16 characters. To really be certain
we are using the same input, you'll have to
verify it.

    You might add something like this. Print the
report near the program end. You should get a list
of arguments, followed by results.

$R723CCPU=&floatmvs(substr($_record,$offsec+32,8));

push @report, [
        substr( $_record, $offsec + 32, 8 ),
        $R723CCPU ];

    .
    .
    .

printf "%s => %s\n\n", @$_ foreach @report;


    If the results are fine here, check them
against the sub you presented. Do this check in
a separate script.


foreach my $arguments ( @report ) {
    my $result = floatmvs( $arguments->[0] );

    printf "%-6s --- %s => %s\n",
        $result == $arguments->[1] ? 'true' : 'false',
        $arguments->[0],
        $result;
}

    If everything comes up true, we have
eliminated errors due to copying and the
modification of the result by a module in the
original script.

    When testing a rewrite of a section of code
do the testing under very controlled conditions.
Know exactly what the input and output is.
Isolate that code in a separate script when
possible. Do a *lot* of testing.

    When you are satisfied. Test some more.
Then plug it back into the script and test some
more. Never assume the new code will work by
logically stepping through the program. Actually
Test it.


: : 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 );
: }
: 

: I think the only difference between your
: subroutine and mine is the way you split the
: bits.

    That's not the only one. Your subroutine
uses variables that are not in scope to the
subroutine. I'm referring to $start, $bit,
$bitpos, and $val.

    My version uses lexically scoped variables
only. Chances are they are both as fast. You'll
have to benchmark them to find out.


HTH,

Charles K. Clarkson
-- 
Mobile Homes Specialist
254 968-8328




-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to