www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/12/03/04:58:35

From: mert0407 AT sable DOT ox DOT ac DOT uk (George Foot)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Problems with DJGPP V2.01 - atof() function
Date: Mon, 02 Dec 1996 17:58:26 GMT
Organization: Oxford University
Lines: 55
Message-ID: <32a3151a.978532@news.ox.ac.uk>
References: <329e68a5 DOT 10316617 AT news DOT ua DOT pt> <32A03F1D DOT 4967 AT pobox DOT oleane DOT com>
NNTP-Posting-Host: mc31.merton.ox.ac.uk
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

On Sat, 30 Nov 1996 14:05:17 GMT, Francois Charton
<deef AT pobox DOT oleane DOT com> wrote:

>float f;
>int i,j;
>i=(int) (1.13*100.0);
>f=1.13*100.0;
>j=(int) f;
>printf("%d %d\n",i,j);
>
>
>prints 112 113...
>
>And this is not because you don't have a FPU : I got a 486DX.
>I'd say this is a parsing problem, with the way DJGPP represents 
>internally floating point numbers : 

I don't think this is quite correct... It's not a parsing problem, and
it's not DJGPP's (or gcc's) fault. I think it's more a problem with
converting binary floating point into decimal, combined with a lack of
understanding of the cast from float to int.

Last things first: the cast from float to int does not round the
number; it just returns the greatest integer smaller than the argument
(like floor(x)). Consequently, (int)112.9999999... = 112, not 113. If
you want 'standard' rounding, add 0.5 before casting.

And the main problem (I think...): Base conversions of floating point
numbers cannot always come out correctly - in fact they rarely do. As
an example, consider base 3 and base 10. We will convert from base 3
to base 10...

Calculation         base 3                           base 10
y = 1/3             0.1                              0.333333333
x = y*3             0.1 * 10                         0.333333333 * 3
  = 1               1                                0.999999999
floor(x)            1                                0

I can't really explain this in words... It is unavoidable. What you
are seeing with 112 vs 113 is a similar problem, but between decimal
and binary.

Bear in mind that floats and doubles are only approximations; their
resolution is limited. If you take care to round 'correctly' by adding
0.5, as mentioned above, you should be okay. Elsewhere in this thread,
I think, a macro has been suggested:

#define _round(x) ((int)(floor((x)+0.5)))

or something similar - possibly without the floor... it isn't strictly
necessary since it's implicit in the cast. Whether it's good practise
to include it or not, and whether it's optimized out of the final
code, I don't know...

George Foot

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019