help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Division in C++


From: Robert Heller
Subject: Re: Division in C++
Date: Tue, 12 Jul 2005 00:10:25 +0200

  Onno Garms <garms@gmx.de>,
  In a message on 11 Jul 2005 10:50:08 -0400, wrote :

OG> Hello,
OG> 
OG> I have a short sample program that hangs on one of my
OG> computer when I compile in debug mode. The program works
OG> fine on my other computers or if I compile optimized.
OG> 
OG> The problematic computer and compiler are quite old (gcc2.95
OG> on a Pentium PC running Linux), but I wonder if the problem
OG> will occur with other compilers on other computers if I
OG> change the numbers.
OG> 
OG> Here is the code:
OG> 
OG> int main ()
OG> {
OG>   double a = 96.03755458500125997;
OG>   double b = 3.0;
OG>   double c;
OG> 
OG>   while (1)
OG>   {
OG>     c = a/b;
OG>     if (a/b<=c) break;
OG>   }
OG> }
OG> 
OG> Can anybody explain why this hangs?
OG> 
OG> What I want the program to do in the loop is the following:
OG> 1. compute a/b
OG> 2. compute a/b again
OG> 3. compare to previous result
OG> 4. see that it is the same and break the loop
OG> 
OG> However the program runs in an endless loop.
OG> 
OG> Regardless of any rounding errors, a/b should always return
OG> the same value, shouldn't it?

Depends :-).  Depending on an equality test with floating point
arithmetic on a computer can be problematical, because of the way
computers handle floating point arithmetic.  Note that different
*vintages* of x86 processors have different FPUs as well.

What you want to do is use an Epsilon type of test:

#include <math.h>

#define Epsilon (.00001)

int main ()
{
  double a = 96.03755458500125997;
  double b = 3.0;
  double c,d,x;

  while (1)
  {
    c = a/b;
    d = a/b;
    diff = fabs(c-d);
    if (diff < Epsilon) break;
  }
}


OG> 
OG> Experiments:
OG> - Storing the result of the second computation in another
OG>   variable d and then comparing d to c works correctly.
OG> - if (static_cast<double>(a/b)<=c)
OG>   endless loop
OG> - Finally, the program below prints "not yet" (and nothing
OG>   else):
OG>   while (1)
OG>   {
OG>     c = a/b;
OG>     if ((d=a/b)<=c) break;
OG>     std::cout << "not yet\n";
OG>     if (d<=c) break;
OG>     std::cout << "but now\n";
OG>   }
OG> 
OG> Does the gnu compiler apply "optimizations" that cause the
OG> behaviour? Which ones? (I compile without options.)
OG> 
OG> Or what else causes this strange behaviour?
OG> 
OG> Greetings,
OG> Onno
OG> [This is a small enough loop that I'd just look at the assembler code.
OG> -John]
OG>                              

                                     \/
Robert Heller                        ||InterNet:   heller@cs.umass.edu
http://vis-www.cs.umass.edu/~heller  ||            heller@deepsoft.com
http://www.deepsoft.com              /\FidoNet:    1:321/153






                                                                       


reply via email to

[Prev in Thread] Current Thread [Next in Thread]