-----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

Reply via email to