-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 16 Mar 2007 at 21:52, Bill Luebkert wrote:
> That can be resolved by using a smaller value than .05. Actually, I
> use something like this to do my rounding when CPU isn't important :
>
> sub round ($;$) { # $ret = round ($num, [$digits:2])
> my ($num, $dp) = (@_, 2); # default decimal places is 2
> int ($num * 10 ** $dp + ($num < 0 ? -.5 : .5)) / 10 ** $dp;
> }
>
...
>
> No, that's not what I intended to do. You can still use (s)printf
> alone to do the job - just use something smaller than 1/2 of the next
> place (like .01) or use a routine like the one above for something
> more robust. I never use int in the process - but that's just me.
Actually, if you look at the code you gave.. You *are* scaling the number prior
to "rounding",
except all in one line instead of doing it in steps. Which is how I would have
done it too,
really, but easier for others to understand the code if it's broken down into
steps ;-). (You
also account for negtive floating point values, which I didn't -- my error!
:-P) Of course,
scaling the number is itself a mathematical operation, which may introduce
additional
rounding errors due to the binary floating point format.
Anyhow, the problem with the first solution of simply adding 0.05 is that
sprintf rounds the
number already. By adding that 0.05, you're changing the very value that
sprintf is rounding.
Add in the issues of the floating point format and sprintf's internal rounding
routine, and
well.. You end up with an entirely incorrect result. The only way it would be
close to correct
is *if and only if* sprintf didn't round, but merely stopped printing digits
after the specified
number have been printed -- IE, if it did an integer truncation, same as our
other routines
were doing explicitly.
I said "close" because there's still the issue of binary floating point being
unable to express
some decimal floating point numbers exactly. And the only way to avoid that is
to to do
ASCII or BCD math instead of binary floating point math, which is CPU
intensive. There are
other methods, as well, and as someone else mentioned, there's different kinds
of rounding
as well -- But I'm limiting myself to the simple case how humans are taught to
round in
grade school with simple math. If someone wants something more, there's plenty
of texts
and resources available on numerical methods and algorithms which go into quite
some
detail and the how's and why's.
Cheers,
Cas
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (MingW32)
iD8DBQFF/voQtSHnwqiHnD4RArY0AJ94wdDAkMAegmbvi5kHG/k4ijlvHgCgsQg4
ud6qyWfKH56P576wzN7zp5M=
=BKnv
-----END PGP SIGNATURE-----
_______________________________________________
Perl-Win32-Users mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs