help-gplusplus
[Top][All Lists]
Advanced

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

Re: g++ bug with double function result in <= expression? (corrected)


From: Guy Harrison
Subject: Re: g++ bug with double function result in <= expression? (corrected)
Date: Wed, 06 Oct 2004 22:00:00 GMT
User-agent: KNode/0.7.7

Jonathan Knispel wrote:

> [Sorry for the repost, I accidentally included bogus code in the original]
> 
>   This looks a bit like a compiler bug to me, but I may be missing
>   something
> obvious.  :-)

Floating point equality tests = avoid like plague! :-)
 
>   The code's below.  "a" and "b" are a pair of structs with identical
> values, but "a.toReal() <= b.toReal()" returns true if toReal() is defined
> with a float return value (expected) and false if defined with a double
> return value (huh?).  If I assign the results of the calls to a pair of
> appropriately typed variables and test the variables with <=, the problem
> goes away (workaround).
> 
>   Here's the sample output from a couple of runs:
> 
> Using double
> a < b false
> a <= b false
> ad < bd false
> ad <= bd true
> 
> Using float
> a < b false
> a <= b true
> ad < bd false
> ad <= bd true
> 
>   I've tried with g++ 3.2.2 (i386-redhat-linux), 3.3.3 (i586-suse-linux)
>   and
> 3.4.2 (i686-pc-linux-gnu).  Stepping through in gdb, the values all look
> fine, but the <= test goes through to the false logic, even though
> evealuating "a.toReal() <= b.toReal()" in gdb returns true.  Any ideas?
> 
> Thanks in advance,
>                                                            Jonathan
> 
> #include <sys/time.h>
> #include <iostream>
> 
> using std::cout;
> 
> #if 1
> 
> typedef double RealType;
> const char* realTypeName = "double";
> 
> #else
> 
> typedef float RealType;
> const char* realTypeName = "float";
> 
> #endif
> 
> struct TimeVal : public timeval
> {
>     TimeVal(RealType t) {
>         tv_sec = static_cast<unsigned int>(t);
>         tv_usec = static_cast<unsigned int>(1e6 * (t - tv_sec));
>     }
> 
>     RealType toReal() { return tv_sec + 1e-6 * tv_usec; }
^^^
Fault. You can hide the problem by changing 1e-6 to 1000000 but the
fundamental issue is the class uses floating point. You need a precise
representation (if floats "worked" then timeval would use one). Rough hints
on possible ctors...

 TimeVal (std::time_t s, long u);
 TimeVal (const std::pair<std::time_t,long> &);
 TimeVal (const std::string &);

> };
> 
> int
> main(int argc,
>      char** argv)
> {
>     cout << "Using " << realTypeName << '\n';
> 
>     TimeVal a(2.1);
>     TimeVal b(2.1);
> 
>     if (a.toReal() < b.toReal())
^^^
You can hide this...

bool operator<(const TimeVal &)const;

...now you can write...

 if (a < b)

>         cout << "a < b true\n";
>     else
>         cout << "a < b false\n";
> 
>     if (a.toReal() <= b.toReal())
^^^
Ditto - operator<=(const TimeVal &)const;

>         cout << "a <= b true\n";
>     else
>         cout << "a <= b false\n";
> 
>     RealType ad = a.toReal();
>     RealType bd = b.toReal();
> 
>     if (ad < bd)
>         cout << "ad < bd true\n";
>     else
>         cout << "ad < bd false\n";
> 
>     if (ad <= bd)
>         cout << "ad <= bd true\n";
>     else
>         cout << "ad <= bd false\n";
> }



reply via email to

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