Message-ID: <32A18E63.3F09@pobox.oleane.com> Date: Sun, 01 Dec 1996 14:55:47 +0100 From: Francois Charton Organization: CCMSA MIME-Version: 1.0 To: djgpp AT delorie DOT com Subject: Re: Problems with DJGPP V2.01 - atof() function References: <329e68a5 DOT 10316617 AT news DOT ua DOT pt> <57mtq1$4mo AT vidar DOT diku DOT dk> <32A02DD1 DOT 1157 AT pobox DOT oleane DOT com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Bryan Anderson wrote: > > On Sat, 30 Nov 1996, Francois Charton wrote: > > > > > int main(void) > > { > > char ch[8]="1.13"; > > int result, otherresult; > > float f; > > result=(int)(atof(ch)*100.0); > > f=atof(ch)*100.0; > > otherresult=(int) f; > > printf("result: %d otherresult:%d\n", result, otherresult); > > return 0; > > } > > > > On my machine I get result: 112 and otherresult: 113... > > > > It is not a bug. It is a fundamental problem: decimals are held > imprecisely because many decimals have an infinite number of binary > digits after the binary point. You cannot beat this. > I agree that floating point representation is imprecise, and that casting a float to an int is not a good way to round it. But this was not the point I was trying to make : to me: int i; i=(int) (atof(ch)*100.0); and float f; int i; f=atof(ch)*100.0; i=(int) f; are two syntactically equivalent expressions (if f is not used after, an optimising compiler could even optimise it out...), and hence the result of their evaluation should be the same (maybe imprecise, but the same...). But this is not the case : the first "i" evaluates to 112, and the second to 113... (and no this is not a floating point representation problem, like when you add a large quantity to a small one: the mathematical calculations are just the same, it is just that you use a variable or not to store the intermediary results). The explanation (thanks, Eli!) seems to be that the calculation result (atof(ch)*100.0) is done in internal 80bit FPU representation, and that when it is written into f (a 32bit float), it is changed. Samely double d; int i; d=atof(ch)*100.0; i=(int)d; Evaluates to 112. This is quite interesting : the "more precise" 80bit number, or the cast to double gives the wrong answer (mathematically I mean), whilst the "rough" float truncate yields the right one... (And the truncated number is bigger than the "less truncated" one: this is not what could be expected from a truncature operation on a positive number). Francois