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>