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 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