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 >