Bug#175809: Strange or incorrect floating point behaviour
Package: g++-3.2
Version: 3.2.2 20021212 (Debian prerelease)
Note that this problem most likely is present in other g++ versions, and
also, in similar forms, in other gcc languages.
It was discussed in comp.lang.c++.moderated, cf.
news:<atq355$9or$1@esel.cosy.sbg.ac.at> and the followup postings.
Posters suggested it might be a bug in the implementation of
-ffloat-store and/or related to floating point expressions evaluated at
compile-time and at runtime with different precisions.
Mathematically, a >= b implies ka >= kb for k >= 0. While I'm well
aware that not all properties of the reals carry over to floating point
arithmetic, I certainly would expect this *particular* implication to
carry over. However, g++ -O3 thinks otherwise.
In the code below, the last assertion fails under certain circumstances.
It's these circumstances which make the behaviour really mysterious:
The assertion does *not* fail if *any* of the following conditions is
satisfied:
1) The bound() template is replaced by a function. (Change the #if 1 to
#if 0.)
2) Lines (1) or (2) are commented out.
3) 2.5 is replaced by other values, e.g. 4.
4) -O2 is specified instead of -O3 (it *does*, however, fail with
-O2 -ffloat-store).
My first guess was that this has something to do with internal usage of
80 bit floating point values, but this doesn't go well with observation
4).
#include <cassert>
#if 1
template< typename T > inline void bound( T & x , T const& u
) {
#else
inline void bound( double& x , double const& u
) {
#endif
assert( 1. <= u ) ; // (1)
if( x < 1. ) { x = 1. ; } // (2)
if( x > u ) { x = u ; }
}
int main() {
const double u = 2.1 ;
double x = 3 ;
bound( x , u ) ;
assert( u >= x ) ;
assert( 2.5*u >= 2.5*x ) ; // fails!!!
}
--
| voice: +43 (0)676 6253725 *** web: http://www.cosy.sbg.ac.at/~gwesp
|
| Passts auf, seid's vuasichdig, und lossds eich nix gfoin!
| -- Dr. Kurt Ostbahn
Reply to: