www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/02/06/17:57:04

From: cziwkga AT ulcc DOT ac DOT uk (Kevin Ashley)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: double-->int: What's wrong here?
Date: 6 Feb 1997 18:16:12 GMT
Organization: University of London Computer Centre
Lines: 54
Distribution: world
Message-ID: <5dd75c$1g3@calypso.ulcc.ac.uk>
References: <32f887b7 DOT 44544 AT news-win DOT inp DOT nsk DOT su>
Reply-To: k DOT ashley AT ulcc DOT ac DOT uk
NNTP-Posting-Host: silver-e.ulcc.ac.uk
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

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 -


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