On Tue, 14 Oct 2003, Malloch, Charles B wrote:

> I'm of the opinion that, as rounding is generally only for the purpose of
> *displaying* a result, that the rounding operation should be delayed until
> the last possible moment. Thus, in general, it's better to do all the adding
> and other stuff and then round just prior to printing.
>
> Look at it this way: rounding throws away information, specifically that
> embodied in the digits that get rounded off. Computers can generally handle
> all that information. It's only when they need to show it to *people* that
> they need to dumb it down ;)

Well, in this case you get the rounding for every number and every math
operation, just not the one you think you're going to get.

Just as decimal math can't accurately represent 1/3, binary floating point
numbers can't accurately represent 1/10. (Which can be something of an
issue, as you might expect) Every decimal constant your program uses with
a fractional part that can't be composed of the sums of powers of two
(1/2, 1/4, 1/8, 1/16, and so on) will be represented by something that's
close, but not quite right.

Usually, though *not* always, the errors cancel, or at least stay within
reasonable levels of tolerance, but that's not universal, and it can lead
to some counter-intuitive and, with numbers that are a result of a large
series of math operations, occasionally very wrong answers.

What you get is usually good enough, and most (though, sadly, not all)
people who will be affected by the error introduced with the inexact
representation are in a position to compensate for it, but it still
catches people by surprise.

As an example, if your doctoral dissertation is based on the results of a
lot of numerical analysis, it would be a darned good idea to keep in mind
the effects of binary representation on constant terms and the errors that
propagate from there. (In addition to whatever error margins you have on
the original data, of course)

You'd also be very ill-advised to do much financial math with floats--as
you can see it takes very few operations to see penny-level errors.
Multiply that by a couple of hundred thousand (or million) calculations
for your average bank and, well, that's a lot of potential cash. I'd also
*really* prefer you not do payroll calculations (at least not on *my*
paycheck :) with floating point math. Fixed-point math (generally with 4
decimal places and an implied decimal point on a 32 or 64 bit integer) is
more appropriate in those cases.

Not that there's anything wrong with floats--they're just fine at what
they do. They just don't quite do what people think they do, which is
where the problems creep in.

                                        Dan

> -----Original Message-----
> From: Dan Sugalski [mailto:[EMAIL PROTECTED]
> Sent: Monday, October 13, 2003 2:56 PM
> To: Bill Stephenson
> Cc: mac osx list
> Subject: Re: Weird math...
>
>
> On Mon, 13 Oct 2003, Bill Stephenson wrote:
>
> > I've got a script that takes numbers similar to those below and then
> rounds
> > them and adds them together using code similar to what is below.
> [snip]
> > The code above prints this result (system 10.1.5, perl 5.6.0):
> >
> >     1.66, 1.75
> >
> > But shouldn't it be:
> >
> >     1.66, 1.76
> >
> > or:
> >
> >     1.65, 1.75
> >
> > I'm no math wizard, so if someone could please take the time and tell what
> > I'm missing here I would very much appreciate it!
>
> Welcome to the wonderful world of inexact representations.
>
> You're getting bitten by some fundamental issues with floating point
> representations of numbers. Floating point fractions are base 2, so they
> can't properly represent anything that's not base 2. (And, since our
> decimal fractions are base 10, that can be a lot of 'em)
>
> There's more explanation in the perl faq, along with some workarounds.
>
>                               Dan
>

Reply via email to