Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

To round a float value doesn't work correctly sometimes

Status
Not open for further replies.

BitsAndPieces

Programmer
Apr 24, 2002
6
DE
I recently found out that FloatToStrF(Value, Decplaces) sometimes makes mistakes !!

I wanted to have 23.0005 to be rounded to 3 decimal places and put into a string. And I got '23.000' !?!?
When I tried the same with 12.0005 I got '12.001' !!!

I could find out that 23.0005 was not really used by Delphi's FloatToStrF but it used 23.0004999999...99999 instead.

How can I write a function that rounds float values CORRECTLY ??

Thanks a lot
Thomas
 
There are some other functions that can be used to convert a float to a string, such as FloatToStr, FloatToText, FloatToTextFmt, FormatFloat and Format. Another option would be to say something like
Code:
FloatToStr(Round(n*1000)/1000)
, so that the rounding work is done by the math function instead of the formatting function.

But yeah, as you suggest, you may have hit the fact that floating point formats are imprecise. Try using the Currency data type, or use scaled Integers. These both offer the perfect accuracy you seek; though of course they're not useable over a wide range of magnitudes like real real types. -- Doug Burbidge mailto:doug@ultrazone.com
 
if you want .00499 to round down, but .004999 to round up, add 0.000001 to value, ie
FloattoStrF(value+0.000001,decimals,etc)

0.004998 -> 0.004999 rounds down
0.004999 -> 0.005 rounds up


You decide where to draw the line
 
Thanks to all of You !
Even though none of your answers could do the complete job You gave me very good hints ! Thank You very much !!

The routine that I will try now is a mixture of some of Your answers :

For n > 0 :
FloatToStr( Trunc(n*1000 + 0.5 + 0.00000001) / 1000 )

For n < 0 :
FloatToStr( Trunc(n*1000 - 0.5 - 0.00000001) / 1000 )

 
Hi BitsAndPieces

I had a similar problem in a different language (development environment.) No matter what I did, the dam thing kept making mistakes (the values in my App did not match the values when posted to Sage Accounts.)

The rounding problem did plague my life for ages. In the end - I simply wanted to round up to a monetry value so I was not interested in anything more precise than 2-3 decimal places.

So bearing that in mind, I simple chopped off any trailing decimal points that I did not need - then rounded up (did the conversion.) I firstly converted the number (un-molested) to a string - I then copied the number of characters I was interested in (including the decimal point) using one of the string copy routines.

The exact details of the conversion (which string copy routines etc) will depend on your language. This is just a non-platform specific approach you may wish to consider.

Cheers..

Opp.
 
Don't forget that No digital computer can deal with floating point numbers with absolute accuracy, what ever you do will be a compromise of some kind.
It's all down to how numbers are stored in memory as deccimal powers of 2
(2 to the .5) (2 to the .25) etc. I wont go into this in detail (have to get my books out!!) but small fractions will result in (small) errors.
Steve..
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top