in a class wrapping a double[3], for certain values a > test will fail. The same code using a raw array is correct. This only occurs for certain values in the array, and only when optimization is turned off "-O0". The simple class in 'foo.cc' below illustrates the problem. Release: 3.2 Environment: System: Linux fairway.math.uwaterloo.ca 2.4.18-10 #1 Wed Aug 7 10:26:48 EDT 2002 i686 unknown Architecture: i686 host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: i686-pc-linux-gnu configured with: ../configure --prefix=/opt/gcc-3.2 --enable-languages=c,c++,f77 How-To-Repeat: [simon@fairway tmp]$ g++ --version g++ (GCC) 3.2 Copyright (C) 2002 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. [simon@fairway tmp]$ g++ -O0 foo.cc;./a.out in vec3 0.8 is greater than 0.8 in double[3] 0.8 is not greater than 0.8 in vec3 -0.1 is not greater than -0.1 [simon@fairway tmp]$ g++ -O1 foo.cc;./a.out in vec3 0.8 is not greater than 0.8 in double[3] 0.8 is not greater than 0.8 in vec3 -0.1 is not greater than -0.1 [simon@fairway tmp]$ foo.cc --- #include <iostream> class vec3 { public: double operator[](const size_t i) const {return x[i];} double& operator[](const size_t i){return x[i];} private: double x[3]; }; int main(){ vec3 u,v; u[0]=u[1]=u[2]=0.9; v[0]=v[1]=v[2]=0.1; std::cout << "in vec3 " << u[0]-v[0] << " is"; if ((u[0]-v[0]) > (u[1]-v[1])) ; else std::cout << " not"; std::cout << " greater than " << u[1]-v[1] << std::endl; double x[3],y[3]; x[0]=x[1]=x[2]=0.9; y[0]=y[1]=y[2]=0.1; std::cout << "in double[3] " << x[0]-y[0] << " is"; if ((x[0]-y[0]) > (x[1]-y[1])) ; else std::cout << " not"; std::cout << " greater than " << x[1]-y[1] << std::endl; u[0]=u[1]=u[2]=0.0; v[0]=v[1]=v[2]=0.1; std::cout << "in vec3 " << u[0]-v[0] << " is"; if ((u[0]-v[0]) > (u[1]-v[1])) ; else std::cout << " not"; std::cout << " greater than " << u[1]-v[1] << std::endl; return 0; }
Fix: unknown. I'll have a look at the asm output when I have a chance.
State-Changed-From-To: open->closed State-Changed-Why: Not a bug. This is the well-known excess precision issue. The extended precision result of the subtraction is 0.80000000000000001665334536937734811 whereas the result rounded to double precision is 0.80000000000000004
From: Richard Henderson <rth@redhat.com> To: Simon Alexander <sk2alexa@math.uwaterloo.ca> Cc: rth@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org, nobody@gcc.gnu.org, gcc-gnats@gcc.gnu.org Subject: Re: c++/7935: floating point test of ">" fails on -O0, not on -O{1,2,3} for certain values double precision float accessed by operator[] in wrapper class (on ix86) Date: Tue, 17 Sep 2002 08:46:19 -0700 On Tue, Sep 17, 2002 at 09:12:06AM -0400, Simon Alexander wrote: > I am aware of the issues surrounding excess precision. However, if > this is merely a precision issue, can you explain why it *only* occur > when wrapped by a class (not with a raw array), and *only* with -O0 ? Your sample set was probably too simple. With inline accessors, -O0 and a single basic block would be the only time you've got a function call between the two computations to force the data out of the fp registers. r~
From: Simon Alexander <sk2alexa@math.uwaterloo.ca> To: rth@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org, nobody@gcc.gnu.org, sk2alexa@math.uwaterloo.ca, gcc-gnats@gcc.gnu.org Cc: Subject: Re: c++/7935: floating point test of ">" fails on -O0, not on -O{1,2,3} for certain values double precision float accessed by operator[] in wrapper class (on ix86) Date: Tue, 17 Sep 2002 09:12:06 -0400 rth@gcc.gnu.org writes: > Synopsis: floating point test of ">" fails on -O0, not on -O{1,2,3} for certain values double precision float accessed by operator[] in wrapper class (on ix86) > > State-Changed-From-To: open->closed > State-Changed-By: rth > State-Changed-When: Mon Sep 16 22:26:45 2002 > State-Changed-Why: > Not a bug. This is the well-known excess precision issue. > > The extended precision result of the subtraction is > > 0.80000000000000001665334536937734811 > > whereas the result rounded to double precision is > > 0.80000000000000004 > > http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=7935 I am aware of the issues surrounding excess precision. However, if this is merely a precision issue, can you explain why it *only* occur when wrapped by a class (not with a raw array), and *only* with -O0 ? S.
Reopening to ...
To close as a dup of bug 323. *** This bug has been marked as a duplicate of 323 ***