[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
- Division in C++, Onno Garms, 2005/07/11
- Re: Division in C++,
Robert Heller <=
- Re: Division in C++, Antoun Kanawati, 2005/07/12
- Re: Division in C++, Marcin 'Qrczak' Kowalczyk, 2005/07/12
- Re: Division in C++, Michael Tiomkin, 2005/07/12
- Re: Division in C++, Florian Weimer, 2005/07/12
- Re: Division in C++, Henry Spencer, 2005/07/12