m = min(v1, v2); if (m != v1 && m != v2) cout << "Help!!!";

Hi guys.

I was writing a simple program that performs an event-driven modelling of customers que and found a strange problem which i don't get how to explain.

I do the next operations and get a very strange result:
1
2
3
4
SomeClass val1, val2;
Float_t min = std::min<Float_t>(val1.getSumm(), val2.getSumm());
if (min != val1.getSumm() && min != val2.getSumm())
    std::cout << "Why?" << std::endl;

1
2
3
4
    inline Float_t getSumm() const 
    {
        return op1_ + op2_;
    }

Values op1_ and op2_ don't change while the std::min and next test occurs, but sometimes i see "Why?" and sometimes don't

Files to reproduce a bug (for Linux) can be found here (There is also a fix, but i just guessed with it):
http://dl.dropbox.com/u/30752769/Bugrep/bugrep.cpp
http://dl.dropbox.com/u/30752769/Bugrep/makefile
http://dl.dropbox.com/u/30752769/Bugrep/test_bug.sh

To run it:
./test_bug.sh

Zero string in the hexdump indicates that bug occured, and ones that it didn't.

Thanks.
Last edited on
Floating point comparisons? Those are tricky :)

http://floating-point-gui.de/errors/comparison/
The code works fine on VS2010 - no false positives with 1000000 comparisons.

It shouldn't be floating point errors, since the result is calculated using the same method each time.
This has to do with the x87 FPU, which operates with a precision of 80 bit. double is 64 bit, causing the result to be truncated when moving it from a FPU register to memory.

Now it might happen that a freshly calculated value (e.g. val1.getSumm()) that is still in a 80-bit register is compared with a value that was already truncated to 64 bit (min) and so two values that were once equal (when they were both 80 bit) might no longer be.

The problem does not appear when compiling for x86_64 or when specifying -mfpmath=sse on 32-bit, as SSE only supports 32 bit and 64 bit precision anyway.
Last edited on
Floating point comparisons? Those are tricky :)

In this particular situation nearlyEqual comparison is not needed. (Could you please see the fix))

It shouldn't be floating point errors, since the result is calculated using the same method each time.

I also think about this, but all points on it.
Maybe it's a gcc related problem.

#g++ -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.4.5 (Debian 4.4.5-8)
Last edited on
Great catch by Athar
Great catch by Athar

+1.

When i switched to long double type everything began to work fine (on my machine).
Thanks.
Topic archived. No new replies allowed.