Mail Archives: djgpp/1997/02/06/17:57:04
In article <32f887b7 DOT 44544 AT news-win DOT inp DOT nsk DOT su>, myskin AT inp DOT nsk DOT su (Vyacheslav O. Myskin) writes:
|>Hi everybody!
|>
|>Please explain me what is wrong with this:
|>
|>------------------------------------------------------------------
|>#include <stdio.h>
|>
|>int main()
|> {
|> double d1,d2;
|> int n1,n2;
|>
|> d1=1./4300.;
|> n1=(int)(.05/d1);
|> d2=.05/d1;
|> n2=(int)d2;
|> printf("n1=%d n2=%d d2=%f\n",n1,n2,d2);
|> return 0;
|> }
|>-------------------------------------------------------------------
|>Compiled with DJGPP 2.01, options: -O0 -g -Wall
|>
|>The output is:
|>n1=214 n2=215 d2=215.000000
|>
|>So why n1 is not equal to n2?
Very short answer: Rounding
Not so short: Just because two expressions are algebraically equivalent
doesn't mean that they will give the same answer. In fact, even the same
expression can validly return different answers at different times if
anything other than integer or logical operations are involved.
Fuller answer: The calculation is highly numerically unstable. A change of
1 in the 15th significant digit of (1./4300.) makes the second computation
equal either 215.0000000 or 214.999999999. The computation of n1 does
the calculation using 80 bit floats, and then gets the FPU to convert
the 80 bit result to integer internally, before storing the result. This
yields the (presumably more accurate) 214.999999... as the floating point
number, which gets truncated to 214 using the float->int conversion rules.
n2, however, is computed using the 64-bit result stored in d2, which
is slightly less accurate than the original 80-bit value. That one digit
difference in the 15th significant digit turns 214.99999... into 215.000000.
If you depend on this, use rounding rather than truncation when converting
float/double to int (ie. n1 = (int)((double expression)+0.5)), but this
still doesn't really resolve the problem.
-----------------------------------------------------------------------------
Kevin Ashley K DOT Ashley AT Ulcc DOT ac DOT uk
Development Manager http://www.ulcc.ac.uk/staff/Kevin+Ashley
University of London Computer Centre. ...ukc!ncdlab!K.Ashley
This is not a signature
- Raw text -