Re: Simple Rounding
by borisz (Canon) on Mar 25, 2004 at 15:39 UTC
|
printf "%.2f", 1100.64686081907;
| [reply] [d/l] [select] |
Re: Simple Rounding
by b10m (Vicar) on Mar 25, 2004 at 15:44 UTC
|
$foo = 1100.64686081907;
$bar = sprintf("%.2f", $foo);
Now $bar will contain 1100.65
Update: changed variable names from $a, $b to $foo, $bar for the first are "special" globals (thanks for the warning, davido)
--
b10m
All code is usually tested, but rarely trusted.
| [reply] [d/l] |
Re: Simple Rounding
by Not_a_Number (Prior) on Mar 25, 2004 at 18:23 UTC
|
As Abigail-II says, sprintf will guarantee two digits after the decimal point. But it won't guarantee consistent rounding. Try this:
my @nums = ( 62, 63, 64, 65 );
for ( @nums ) {
$_ += 0.005;
printf "%.2f\n", $_;
}
Output (at least on my machine):
62.01
63.01
64.00
65.00
To quote Zaxo from the thread (s)printf and rounding woes:
"That is a general property of binary floating-point numbers... If you need consistency in a fixed-point decimal representation, you should scale the numbers to be represented as integers."
dave | [reply] [d/l] [select] |
Re: Simple Rounding
by Roy Johnson (Monsignor) on Mar 25, 2004 at 15:52 UTC
|
| [reply] |
Re: Simple Rounding
by Fletch (Bishop) on Mar 25, 2004 at 15:53 UTC
|
| [reply] [d/l] |
Re: Simple Rounding
by Beechbone (Friar) on Mar 25, 2004 at 15:54 UTC
|
$a = 1100.64686081907;
$b = int($a*100+.5)/100;
but if you just want to print it, (s)printf() would be the better choice.
| [reply] [d/l] |
|
My first thought was, 'Silly guy, why is he writing C code? Doesn't he know the Perl(tm) way?'.
Then I thought, sprintf() is expensive .... how fast is it to run the integer math?
--
TTTATCGGTCGTTATATAGATGTTTGCA
| [reply] [d/l] |
|
There is a subtle, but important difference between
$var1 = sprintf "%.2f" => $number;
and
$var2 = int ($number * 100 + .5) / 100;
$var1 is a PV, that is, the interval variable has a string value, but not a numeric value, while $var2 is an NV, that is, it has a numeric
value, but not a string value. This means that $var1 will have two digits after the decimal point
when printed - sprintf has garanteed that. But that's not necessarely true for $var2. Since you cannot represent 1/100 exactly in binary, you left the
possibility open that if you stringify the number, you end
up with more than 2 characters after the decimal point.
Now, it may not happen in a thousand testcases, but can you
guarantee it will never happen?
See perldoc -q decimal. | [reply] [d/l] [select] |
Re: Simple Rounding
by PERLscienceman (Curate) on Mar 26, 2004 at 02:50 UTC
|
Greetings Fellow Monk!
In the standing philosophy of "There Is Always More Than One Way To Do It" I found this CPAN module, Math::Round, which should also do what you are looking for. I have included a chunk of example/test code below:
#!/usr/bin/perl -w
use strict;
use Math::Round;
my $number=1100.64686081907;
$number=nearest(.01,$number);
print "$number\n";
___OUTPUT___
1100.65
| [reply] [d/l] |