Barry Brevik wrote:
> OK, I needed a routine to round numbers that have decimal places, and
> Perl does not appear to have a *native* function for doing that, so I
> poked around on the internet and found this subroutine:
>  
> sub roundit
> {
>   my($num, $places) = @_;
>   return sprintf "%0.*f", $places, $num;
> }
> 
> I figured that since it uses sprintf, it would be fine, but I decided to
> test it anyway and I'm getting some odd results. The exact program code
> I used is printed below the following results. Anybody have any idea of
> what is going on?

Try this one - the second round sub adds a .5 at one level below the
desired precision (which should only register when you're at a .5,
.05, .005, etc.:

use strict;
use warnings;

my @nums = (
   2.004, 2.014, 2.024, 2.034, 2.044, 2.054, 2.064, 2.074, 2.084, 2.094,
   2.005, 2.015, 2.025, 2.035, 2.045, 2.055, 2.065, 2.075, 2.085, 2.095,
   2.006, 2.016, 2.026, 2.036, 2.046, 2.056, 2.066, 2.076, 2.086, 2.096
);
my $places = 2;

print "$places places:\n";
for (my $ii = 0; $ii < @nums; ++$ii) {
        my $num = $nums[$ii];
        printf "roundit : $num %s\n", roundit ($num, $places);
        printf "roundit2: $num %s\n", roundit2 ($num, $places);
}

sub roundit {
        my ($num, $places) = @_;
return sprintf "%0.*f", $places, $num;
}

sub roundit2 {  # round with fudge factor
        my ($num, $places) = @_;
my $factor = .5 * 10 ** -($places+1);
return sprintf "%0.*f", $places, $num + $factor;

}

__END__

_______________________________________________
ActivePerl mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to