[Israel.pm] Rounding numbers to the nearest quarter???

Jason Elbaum Jason.Elbaum at freescale.com
Thu May 6 07:25:22 PDT 2004


Yuval Kogman wrote:

> More room for error, when there's no need,

The moment you write a function, there's no more room for error. For 
example:

sub round {
   my $val = shift;
   my $increment = shift;

   $val /= $increment if defined $increment;
   $val = int($val + 0.5);
   $val *= $increment if defined $increment;

   return $val;
}

my @args_list = ( "0.6",
		  "12, 10",
		  "2.70, 0.25",
		  "123.4567, 0.01",
		  "53, 7",
		);

foreach $args (@args_list) {
   print "round($args) = ", round(split(',', $args)), "\n";
}


OUTPUT:

round(0.6) = 1
round(12, 10) = 10
round(2.70, 0.25) = 2.75
round(123.4567, 0.01) = 123.46
round(53, 7) = 56

Obviously, you can't get this flexibility of increments from sprintf(). 
I guess you can "round" to base 2, 8 or 16 and convert back to decimal, 
but that's still a very restrictive set of operations.


> sprintf("%.2f",$x);		sprintf("%.2f", $x);

Furthermore, sprintf() doesn't "round numbers" - it stringifies them. If 
you're rounding them to print them, that's fine. If you're planning to 
do math with them (less common, but it happens too), you have to convert 
them to strings and back to numbers each time. The mathematical round() 
function only has to handle numbers. (Of course, the difference in 
runtime would be much more significant in a compiled language with 
built-in numerical types, but I imagine it's significant in Perl as well.)

In general, sprintf() is heavy and slow and not suited to numerical 
operations where efficiency matters. (Actually, it's probably not suited 
to any operations where efficiency matters!)


At least, that's how I see it!


Regards,


Jason Elbaum



More information about the Perl mailing list