www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/12/01/09:27:38

Message-ID: <32A18E63.3F09@pobox.oleane.com>
Date: Sun, 01 Dec 1996 14:55:47 +0100
From: Francois Charton <deef AT pobox DOT oleane DOT com>
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> <Pine DOT SOL DOT 3 DOT 91 DOT 961201085145 DOT 18913B-100000 AT aten>

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

- Raw text -


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