Re: Rounding up in perl
- From: "Peter J. Holzer" <hjp-usenet2@xxxxxx>
- Date: Sun, 21 Dec 2008 14:34:52 +0100
On 2008-12-20 16:39, Tim Greer <tim@xxxxxxxxxxxxx> wrote:
Peter J. Holzer wrote:
As Ilya said, truncating is one of several modes of rounding.
Right. I am well aware of that, and I even said so as well before Ilya
replied.
It's not that int doesn't round, or that
isn't dependable, it just usually isn't the rounding function you
want.
And that is what I said previously, it's not probably want you want,
since it's intent is to truncate (even if that is a method used for
rounding),
We may have a language problem here. I wouldn't say "truncating is a
method used for rounding", but "truncating is a method of rounding". The
former implies that there is only one way of rounding, and truncating is
not rounding, but can be used to implement rounding. The latter implies
that there are many ways of rounding, and trucating is one of them.
and I think that it's not as dependable as other solutions,
Again, we may have a language problem. If I say a method is "not
dependable" I mean that it does give the expected result most of the
time, but sometimes it gives the wrong result, and the problem isn't
immediately apparent.
To borrow an example from a recent thread, replacing a symlink with
unlink($link) if -e $link;
symlink($target, $link);
is not dependable. It works almost all of the time, but there is a
possibility that another process creates $link between the time your
process has removed it and tries to recreate it - and unless you are
used to thinking about race conditions, you may not see that.
OTOH, if you do something like
$y = int($x) # round to nearest int
that's not a question of dependability. That will produce the wrong
answer for 50% of all possible values, and it is immediately apparent
from the definition of the int function, that it is the wrong function
to use in this case. (floor and ceil are of course, just as wrong).
Let's assume you want a function which rounds the way you learned in
primary school: Round to nearest integer, and break ties away from zero.
sub common_round_i { my ($x) = @_; return int($x); }
sub common_round_f { my ($x) = @_; return floor($x); }
sub common_round_c { my ($x) = @_; return ceil($x); }
sub common_round_s { my ($x) = @_; return sprintf("%.0f", $x); }
It is immediately clear that the first three implementations don't do
what you want. The first two round 0.9 down (instead of up) and
common_round_c rounds 0.1 up (instead of down).
common_round_s seems to do the right thing at the first glance:
It rounds 0.1 down, it rounds 0.9 up, it rounds 1.5 up. But it rounds
0.5 down (instead of up), and that is probably not immediately apparent
to someone who hasn't learned a bit about numerical methods. So you
could say that using sprintf is "not dependable" (for the problem you
want to solve - there are good reasons for sprintf working the way it
does and at that point you should probably consider the possibility that
"rounding the way you learned in primary school" may not be what you
really need), while the other ways are not only "not dependable", they
are clearly und utterly wrong.
However, you can use the int, floor, and ceil functions to implement
your rounding function:
sub common_round_i2 {
my ($x) = @_;
return int($x + ($x >= 0 ? 0.5 : -0.5));
}
sub common_round_f2 {
my ($x) = @_;
return $x >= 0 ? floor($x + 0.5) : -floor(-$x + 0.5);
}
sub common_round_c2 {
my ($x) = @_;
return $x >= 0 ? -ceil(-$x - 0.5) : ceil($x - 0.5);
}
All of these are correct (as per specification), and there is no
mathematical reason to prefer one over the others. But common_round_i2
is slightly shorter and doen't need any modules, so I'd prefer that from
a Perl programmer's view.
which I also listed -- which the docs themselves also warn against.
The warning in the documentation is highly confusing. Not really wrong,
but very misleading if you don't already know about these things (and
then you don't need the warning).
hp
.
- References:
- Rounding up in perl
- From: David Groff
- Re: Rounding up in perl
- From: Tim Greer
- Re: Rounding up in perl
- From: Ilya Zakharevich
- Re: Rounding up in perl
- From: Tim Greer
- Re: Rounding up in perl
- From: Ilya Zakharevich
- Re: Rounding up in perl
- From: Tim Greer
- Re: Rounding up in perl
- From: Peter J. Holzer
- Re: Rounding up in perl
- From: Tim Greer
- Rounding up in perl
- Prev by Date: FAQ 2.17 What is perl.com? Perl Mongers? pm.org? perl.org? cpan.org?
- Next by Date: Re: Rounding up in perl
- Previous by thread: Re: Rounding up in perl
- Next by thread: Re: Rounding up in perl
- Index(es):
Relevant Pages
|