This is my first post here, so please excuse my bad english.
Working on a larger project we needed some code to round numbers
(that are prices in a shop) to a precision of 2 digits (%.2f), i.e. from
8.7385 to 8.74. In 'Programming perl', or in the monastery you find this code:
sub round($$)
{
sprintf "%.$_[1]f",$_[0];
}
print round(8.7385, 2); # prints 8.74
which works really nice... until we found out following strange behaviour:
for my $i (0 .. 10)
{
print round($i+0.555,2)," ";
}
# which prints:
# 0.56 1.56 2.56 3.56 4.55 5.55 6.55 7.55 8.55 9.55 10.56
...hm, the decimal part should allways be the same!
from 10 upwards it seems to stay '.56', but now look at this:
for (my $i = 1; $i < \xFFFF; $i <<= 1)
{ print round($i+0.555,2), " "; }
# which prints:
#1.56 2.56 4.55 8.55 16.56 32.56 64.56 128.56 256.56 512.55
#1024.56 2048.55 4096.56 8192.56 16384.56 32768.56 65536.55
#131072.55 262144.55 524288.56 1048576.55 2097152.56 4194304.55
#8388608.55 16777216.56
#
#(You can try with different numbers and different precision as long
# as the last digit is '5' and the precision = number of digits - 1)
So here goes my first question:
- Is there a 'mystical rule' behind this behaviour? (Is ist a bug or is it a feature?)
(Btw. i've tested on Linux and different Windows Systems, Activestate 5.005/5.6.)
And the 2nd question:
I wrote this code to achieve same behaviour (and allways print %.2f in the shop):
sub round2($$)
{
my $var=$_[0];
my $decimal=($var-int(var));
if ($decimal && ((length($decimal)-2)>$_[1]) && ($var=~/5$/))
{
$var=~s/5$/6/;
}
sprintf "%.$_[1]f",$var;
}
# some output:
for (my $i = 1; $i < \xFFFF; $i <<= 1)
{ print round($i+0.555,2), " ", round2($i+0.555,2), "\n"; }
...but it's somewhat obfuscated (and it does not take care of numbers like 1.5E-4).
So any ideas or comments would be appreciated.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.