> Aristotle wrote:
> > Bernie wrote:
> > So: what I want is something to format money correctly,
> whther it is
> > fractional or not. there's the fairly awful:
> >
> > sprintf ($amt =~ /\.\d\d\d/? "%7.3f": "%7.2f"), $amt
> When testing $amt itself, I'd insist on using mathematical
> functions only for the sake of cleanliness -- you never know
> when stringification would surprise you.
I don't believe you can use maths ops with this problem. Mathematically
"1.000" == "1.00" but how I read Bernie's problem these numbers have a
different accuracy and should be printed using different print formats.
It tends to make accountants upset when they see printed lists like
this:
0.999
1.00
1.001
Perhaps a package using overload would be a pure Perl solution? That way
you can explicitly declare the accuracy of your numbers and round
accordingly.
> perl -le'for (@ARGV) { $_ = sprintf "%7.3f", $_; \
> chop if /\.\d\d0\z/; print; }' 1.2, 1.23, 1.234, 1.2345
> 1.20
> 1.23
> 1.234
> 1.234
There's another accountant-unfriendly aspect to using printf rather than
string manipulation. Did you notice that 1.2345 rounded to 1.234, and
not 1.235 as an accountant might expect. Of course it could be your
intent to annoy accountants. :-)
There's even two different 1.2345's (at least on a 32bit machine there
is).
$x = 12345 /10000;
$y = 12345 /1000/10; # Same as $x isn't it?
printf("%20f == %20f Looks OK\n", $x, $y);
printf("%20.3f != %20.3f Eh?\n", $x, $y);
printf("%20.16f != %20.16f Ahah!\n", $x, $y );
See: Perl FAQ 4 "Does Perl have a round() function?..." for some more
nitty gritty and some wholesome preaching from the pulpit?
Alistair
-----------------------------------------------------------------------
Registered Office:
Marks & Spencer p.l.c
Michael House, Baker Street,
London, W1U 8EP
Registered No. 214436 in England and Wales.
Telephone (020) 7935 4422
Facsimile (020) 7487 2670
www.marksandspencer.com
Please note that electronic mail may be monitored.
This e-mail is confidential. If you received it by mistake, please let us know and
then delete it from your system; you should not copy, disclose, or distribute its
contents to anyone nor act in reliance on this e-mail, as this is prohibited and may
be unlawful.
The registered office of Marks and Spencer Financial Services PLC, Marks and Spencer
Unit Trust Management Limited, Marks and Spencer Life Assurance Limited and Marks and
Spencer Savings and Investments Limited is Kings Meadow, Chester, CH99 9FB. These
firms are authorised and regulated by the Financial Services Authority.