Board index » delphi » Floating Point Numbers

Floating Point Numbers

I need to accurately round floating point numbers in Delphi, and this
seemingly simple task appears to be impossible!

The routine I need will look something like this :

Function Rounded (NumberToRound : Double; Places : Word) : Double;

Thus Rounded (10.055, 2) returns 10.06, and more importantly
Rounded (10.055, 2) - 10.06 returns 0 and NOT 1.021E-16 or some other
small number.

 

Re:Floating Point Numbers


Quote
In article <46iunr$...@foible.pix.za> rs000...@pixie.co.za (Russell Smith) writes:
>I need to accurately round floating point numbers in Delphi, and this
>seemingly simple task appears to be impossible!

This isn't simple at all.  Why should 10.055 round to 10.06 and not 10.05?  
There probably isn't any way to represent 10.055 exactly in any of the
floating point formats that Delphi uses, so if it happens to be represented as
10.05499999, it would make a lot more sense to round down rather than rounding
up.

Furthermore, even if it should round up, it's not obvious that there is *any*
simple formula which can take the value 10.055 and return the exact same
floating point number as the compiler interprets the string '10.06' to be.  
Floating point calculations are inherently approximate, and if you don't like
that, you shouldn't use them.

What you should do if you're concerned about exact results is to use an exact
storage format, not floating point.  For example, store 10.055 as the
longint value 10055 and remember to divide by 1000 before interpreting it.

Duncan Murdoch

Re:Floating Point Numbers


Quote
In article <46iunr$...@foible.pix.za>, rs000...@pixie.co.za (Russell Smith) writes:
>I need to accurately round floating point numbers in Delphi, and this
>seemingly simple task appears to be impossible!

>The routine I need will look something like this :

>Function Rounded (NumberToRound : Double; Places : Word) : Double;

>Thus Rounded (10.055, 2) returns 10.06, and more importantly
>Rounded (10.055, 2) - 10.06 returns 0 and NOT 1.021E-16 or some other
>small number.

Your second condition is virtually impossible to guarantee with most
computer implementations of floating point numbers, depending on how you
arrived at 10.055, it may actually be 10.0550000152 or some such.  It's
not really a limitation of Delphi per se, you'd encounter the same
thing in other dialects of Pascal, or in C or FORTRAN.

You might be able to do something with multiplying you values, then
truncating and re-dividing, but there's still possibilities for errors
to slip in.  The stand-by technique is to provide an "Epsilon" factor
against which to test your results, and if they're smaller (or larger
depending on context), you can treat the result as if it were 0.

If you really NEED that kind of absolute precision, you have to go to
fixed point numbers; hovever, most implementations of Pascal (including
Delphi) don't have such things built in; you have to create them
yourself.

HTH

-* Stephen *-
Stephen Posey
University of New Orleans
Email  : S...@uno.edu
WWW    : http://www.uno.edu/~slp

Other Threads