Roy Johnson said:
(e-mail address removed)-berlin.de (Anno Siegel) wrote in message
Your rounding is faster, but it doesn't quite work, in the sense of
always getting the same result as sprintf *or* the mathematically
accurate result.
What is the mathematically accurate result of rounding 0.05 to one
decimal place? The problem is, there are two equally likely candidates,
and mathematics doesn't presume to make a decision. Mathematically,
the result isn't defined.
nround(0.05, 1) yields 0, whereas sprintf('%.1f', 0.05) yields 0.1. Of
course, sprintf('%.1f', 3.05) yields 3.0, and so does Nround.
Algorithms have to make a decision, and standards define how to make
it. I am a little surprised at what IEEE does here (assuming it *is*
IEEE), or rather, I would be surprised if I hadn't long ago given up
being surprised by numeric results.
Here's one that works (in the sense of being mathematically accurate)
for all the values I've tried, but it is only about half as fast as
nround, or 3/4 as fast as sprintf.
Again, there is no "mathematically accurate" solution in the critical
case (where both possible values are equally far off). However, your
solution now differs from sprintf when rounding 0.5 to an integer:
sprintf says 0, stround says 1.
The point of speed is probably moot now. The next Perl will include
Ilya's patch, if the creeks don't rise, and that'll be it for Perl
implementations of rounding.
sub stround {
my ($n, $places) = (@_,0);
my $sign = ($n < 0) ? '-' : '';
my $abs = abs($n);
$sign . substr($abs+('0.'.'0'x$places.'5'),
0, $places+length(int($abs))+1);
}
Hmm... I can't say that I like the mixture of arithmetic and text-
processing, though it may be said to be typical of Perl. If I had to
*prove* an implementation conforms to some standard, I'd prefer a numeric
solution, if possible one that corresponds step by step to the description
in the standard.
Anno