use Math::Round;
All of the common languages suffer from rounding problems inherent in
IEEE rounding (round-to-even and other issues). Math::Round resolves
these issues.
$a=4712.5;
$b=round $a;
printf "%s %5.0f %5.0f\n", $a, $a, $b;
I hit this while comparing SAS output (which does do proper (within
machine limits) "mathematical" rounding that we all learned about in
school. The C libraries from which Perl and other C-lib derived
languages take their rounding functions are the cause of some potential
grief here and comparison with 4 other languages vs. SAS showed SAS
getting it right each time. Using Math::Round - so did Perl. We're
talking way down to DP as well.
This caused the group I work with some issues as I was rewriting some
SAS code in Perl and our regression tests were not matching - and we
were talking adding up millions of rows of data with N DP to be
concerned about. Math::Round fixed that.
Kind regards
Derek Jones
Mr. Shawn H. Corey wrote:
On Tue, 2008-10-07 at 09:02 -0700, Douglas Wilson wrote:
or instead, after selecting, I can use sprintf:
$float_column = sprintf("%1.16e", $float_column);
The first solution is okay if I know in advance which columns are
floats,
while the second solution seems better if I need to dynamically deal
with unknown column types (e.g., "select *").
Does anyone have any better (or just other) ideas?
sprintf is the preferred way of rounding off floats in Perl. There is a
whole branch of mathematics, numerical analysis, which deals with
problems like this, so don't expect things to be easy.
BTW, don't use "SELECT *". If your DBA rebuilds the tables with a
different column order, your code will fail. Specifically name the
columns (or if you really have to, use the _hashref methods to fetch;
that way you can select the correct column via the hash).