This is a known "bug". It happens like that in C as well. Write your own rounding function, or use this one:
# round(789.456,-2) => 800
# round(789.456,-1) => 790
# round(789.456) => 789
# round(789.456,1) => 789.5
# round(789.456,2) => 789.46
sub round {
my ($n, $p) = @_;
my $sign = ($n > 0) ? 1 : -1;
$p ||= 0;
$n *= 10 ** $p;
$n = int($n + .5 * $sign);
return $n / 10**$p;
}
japhy --
Perl and Regex Hacker | [reply] [Watch: Dir/Any] [d/l] |
This sub has the same bug as sprintf.
round(5.245,2) returns 5.25
but
round(9.325,2) returns 9.32
| [reply] [Watch: Dir/Any] [d/l] [select] |
c:\@Work\Perl>perl -wMstrict -le
"for my $f (5.245, 9.325) {
print sprintf '%.20f', $f;
}
"
5.24500000000000010000
9.32499999999999930000
Update: Slight cosmetic change to code example.
| [reply] [Watch: Dir/Any] [d/l] |
2.815 can not be precisely represented by a floating point number
printf("%.20f\n", 2.815);
| [reply] [Watch: Dir/Any] [d/l] |
No, I don't think this is a problem, as for it to be a problem in perl that would require .5 to evaluate as > .5. That is, if it is _over_ half then it will round, and otherwise it will truncate. It has to go one way or the other, neither way is really right or wrong.
The good news is, add a very small number like .000001 and you'll get what you want.
$a = sprintf("%.2f", $a+.00001);
-- Snazzy tagline here
| [reply] [Watch: Dir/Any] [d/l] |
Update:
Just look down at what ChemBoy wrote and forget I ever said
anything. Must be one of those days. | [reply] [Watch: Dir/Any] |
% perl -e 'printf "%1.2f\n", 1.234'
1.23
and
% perl -e 'printf "%1.2f\n", 1.235'
1.24
Which gives me to think that rounding does in principle occur in sprintf and printf. The problem is the floating point representation of base-10 numbers, which occasionally gives you less precision than you though you had. If you really need that precision, hunt around for further discussion on the issue using Super Search, and you'll find plenty.
Update: or just read japhy's response on the original thread.
If God had meant us to fly, he would *never* have give us the railroads.
--Michael Flanders | [reply] [Watch: Dir/Any] [d/l] [select] |