Bug 55787 - Comparisons of double values don't work correctly
Summary: Comparisons of double values don't work correctly
Status: RESOLVED DUPLICATE of bug 323
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: build
Depends on:
Blocks:
 
Reported: 2012-12-22 15:24 UTC by W. Tasin
Modified: 2012-12-31 16:50 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
example code (as .ii) (51.99 KB, application/octet-stream)
2012-12-22 15:24 UTC, W. Tasin
Details

Note You need to log in before you can comment on or make changes to this bug.
Description W. Tasin 2012-12-22 15:24:04 UTC
Created attachment 29027 [details]
example code (as .ii)

A simple comparison shows that floating point operations with the c++-type double doesn't set the floating status flag correctly.

Changing the type of the members of the class Load to float or long double makes the application work correctly.

In the attached example the free function 
bool operator<(const Load &, const Load &); 
doesn't work correctly.

The example returns the output:
Compare: true
instead of
Compare: false

This example was compiled in different configurations and on different machines with the same wrong result:

System configuration 1:
---
Intel(R) Core(TM)2 CPU 6420 @ 2.13GHz
3 GB RAM (pae)
Windows XP Professional Version 2002 SP3
32 bit arch
---
Es werden eingebaute Spezifikationen verwendet.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.7.2/lto-wrapper.exe
Ziel: mingw32
Konfiguriert mit: ../gcc-4.7.2/configure --enable-languages=c,c++,ada,fortran,objc,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgomp --disable-win32-registry --enable-libstdcxx-debug --disable-build-poststage1 -with-cxx --enable-version-specific-runtime-libs --build=mingw32 --prefix=/mingw

Thread-Modell: win32
gcc-Version 4.7.2 (GCC)
---
The build process call was:
g++ -v -save-temps -Wall -pedantic -Wextra -o derror.exe src\derror.cpp

--- derror.cpp ---
// test routine to show the double error
#include <iostream>
#include <stdexcept>
using namespace std;

// class definition
class Load
{
	double m_dPowerOut, m_dEfficiency;
public:
	Load(double powerOut, double eff=1) :
	  m_dPowerOut(powerOut), m_dEfficiency(eff) { };
  	virtual double consumption() const;
  	virtual ~Load() { }
};

bool operator<(const Load &a, const Load &b);

// class method definition
double Load::consumption(void) const
{
	if (m_dEfficiency==0.0)
			throw logic_error("Efficiency must not be 0");
	return m_dPowerOut/m_dEfficiency;
}

/// free function
// ... doesn't work correctly
bool operator<(const Load &a, const Load &b)
{
	return a.consumption() < b.consumption();
}
/*
// ... seems to work correctly, but the float-status-flag IMHO 
//     still isn't correct
bool operator<(const Load &a, const Load &b)
{
	double bcon=b.consumption();
	return a.consumption() < bcon;
}
*/

int main()
{
	try
	{
		Load pump(53.0, 0.43);
		bool cmp=(pump < pump);  // should be false !!!
		cout << "Compare: " << (cmp ? "true" : "false") << endl;
	}
	catch (const exception &ex)
	{
		cerr << "Exception: " << ex.what() << endl;
	}
	return 0;
}
Comment 1 Daniel Krügler 2012-12-22 17:30:37 UTC
Using gcc 4.8.0 20121209 (experimental) (also mingw, but 64-bit on Windows 7) returns "false" for me.
Comment 2 Andreas Schwab 2012-12-22 18:28:49 UTC
Most likely a dup of bug 323.
Comment 3 Richard Biener 2012-12-31 16:12:05 UTC
Use -fexcess-precision=standard

*** This bug has been marked as a duplicate of bug 323 ***
Comment 4 Jonathan Wakely 2012-12-31 16:50:21 UTC
If only ...

cc1plus: sorry, unimplemented: -fexcess-precision=standard for C++