Version: 3.0.0 (using KDE Devel) Installed from: Compiled sources Compiler: g++ 3.2.3 OS: Linux The comparisions in the following testprogram all result in true when invoked directly. When run using valgrind, the comparisons with the result of std::pow with 5.0, 9.0 and 10.0 result in false. The test was compiled with gcc 3.2.3 under i386 and with gcc 4.0 under ppc and returned the same result without valgrind. This is probably related to the 3.0.0 changes in its IEEE754 floating point implementation mentioned in http://www.valgrind.org/docs/manual/manual-core.html#manual-core.limits. Valgrind versions 2.4.1 and lower seem to be unaffected by this problem. Testprogram: #include <iostream> int main( void ) { std::cout << "std::pow( 1.0, 0.5 ) == 1.0 " << ( std::pow( 1.0, 0.5 ) == 1.0 ) << std::endl; std::cout << "std::pow( 4.0, 0.5 ) == 2.0 " << ( std::pow( 4.0, 0.5 ) == 2.0 ) << std::endl; std::cout << "std::pow( 9.0, 0.5 ) == 3.0 " << ( std::pow( 9.0, 0.5 ) == 3.0 ) << std::endl; std::cout << "std::pow( 16.0, 0.5 ) == 4.0 " << ( std::pow( 16.0, 0.5 ) == 4.0 ) << std::endl; std::cout << "std::pow( 25.0, 0.5 ) == 5.0 " << ( std::pow( 25.0, 0.5 ) == 5.0 ) << std::endl; std::cout << "std::pow( 36.0, 0.5 ) == 6.0 " << ( std::pow( 36.0, 0.5 ) == 6.0 ) << std::endl; std::cout << "std::pow( 49.0, 0.5 ) == 7.0 " << ( std::pow( 49.0, 0.5 ) == 7.0 ) << std::endl; std::cout << "std::pow( 64.0, 0.5 ) == 8.0 " << ( std::pow( 64.0, 0.5 ) == 8.0 ) << std::endl; std::cout << "std::pow( 81.0, 0.5 ) == 9.0 " << ( std::pow( 81.0, 0.5 ) == 9.0 ) << std::endl; std::cout << "std::pow( 100.0, 0.5 ) == 10.0 " << ( std::pow( 100.0, 0.5 ) == 10.0 ) << std::endl; std::cout << "std::pow( 121.0, 0.5 ) == 11.0 " << ( std::pow( 121.0, 0.5 ) == 11.0 ) << std::endl; std::cout << "std::pow( 144.0, 0.5 ) == 12.0 " << ( std::pow( 144.0, 0.5 ) == 12.0 ) << std::endl; return 0; }
This problem also affects version 3.1.0 of valgrind.
As you say, this is almost certainly the issue described in the documentation. Julian will know more than me on this but I don't believe there are any current plans to support 80 bit x87 precision. One thing I'm a bit confused about is that you mention PPC in the description - do you mean that this is also failing in the same way on a PPC system? If so then it would rule out the 80 bit issue as that is x87 specific. Compiling -mfpmath=sse on an x86 box would also rule that out. Another possibility would be a rounding mode issue I guess - does --show-emwarns=yes report any warnings about rounding modes? You shouldn't really be doing equality tests like that on floating point values though - it isn't a reliable means of comparing a floating point result.
Yes on ppc the testprogram produces the same result as on x86 without valgrind: all comparisons succeed. I just tested with -mfpmath=sse under Linux/gcc 3.2.3: all comparisons succeed when invoked directly and fail when run using valgrind 3.1.0. So I guess the bit precision can be ruled out for this problem. The --show-emwarns=yes switch does not result in any warnings. >You shouldn't really be doing equality tests like that on floating point values >though - it isn't a reliable means of comparing a floating point result. I know, this comparisons just exist in one of my regression tests, elsewhere they are done with a certain tolerance. But it would still be nice if valgrind produced the same result as the native run of the program.
>I just tested with -mfpmath=sse under Linux/gcc 3.2.3: all comparisons succeed >when invoked directly and fail when run using valgrind 3.1.0. Sorry, it seems that I have missed a warning while compiling with -mfpmath=sse: cc1plus: warning: SSE instruction set disabled, using 387 arithmetics So maybe the precision theory can not be completely ruled out yet. That it works the same way on PPC as on x86 is still strange though.
OK, now I tested on Linux x86_64 (aka amd64) using gcc 3.4.4 and valgrind 3.1.0 compiled for x86_64: The valgrind run is now identical to the native run, with or without -mfpmath=sse set. All equality comparisons succeed.
Interesting - x86_64 will default to SSE maths. Add -msse2 to get SSE support on x86 - so "-fpmath=sse -msse2" should get it to use SSE for the FP code. That might not help if the problem is in libstdc++ of course, unless that was recompiled the same way. It sounds like there might be two issues - the 80 bit precision issue on x86 (not present when using SSE math which is 64 bit) and some sort of PPC issue.
Results with SSE on x86 ("-mfpmath=sse -msse2"): All equality tests succeed when run natively and the tests for 5.0, 9.0 and 10.0 fail when run under valgrind, so the behavior is equivalent to the non SSE tests on the same platform. Note that on PPC/OS X I just ran the test natively, because I have no valgrind on that platform.
So you haven't actually run under valgrind on PPC then? Sorry I think I misunderstood what you were saying about that. By the sounds of it this is the 80 bit x87 issue document in the manual then.
What puzzles me a bit is that natively the test program produces the same results on all platform/compiler combinations using 64bit (SSE/PPC) and 80bit (x86 non SSE) arithmetic, but only the amd64 valgrind produces the same result as the native run.
I'll look into it this week, since I'm looking at FP accuracy issues anyway this week.
I traced a valgrind problem I had to a simpler example. I conjecture that it´s not too much of interest for you. But I want to report it, as it took me a while to understand that although all floats are 64 bit doubles, the intermediate 100100/a is probably 80bit and causes the problem. ----------------------------------- #include <iostream> int main() { double b = 3.6; double a = 60/b; double c = 100100/a; std::cout << c << " " << int( c ) << " " << int(100100/a ) << "\n"; } ----------------------------------- The program gives "6006 6006 6005" with gcc-3.4.2, gcc-4.0.1, gcc-4.1.0 on a Linux simusrv6 2.6.11-gentoo-r9 #2 SMP Fri May 27 11:53:26 CEST 2005 i686 Intel(R) Pentium(R) 4 CPU 3.00GHz GenuineIntel GNU/Linux and Linux gentoo29 2.6.10-co-0.6.2 #5 Sat Feb 5 10:19:16 IST 2005 i686 Intel(R) Pentium(R) 4 CPU 3.00GHz GenuineIntel GNU/Linux But with valgrind and without valgrind but with "-mfpmath=sse -msse2" it produces "6006 6006 6006".
*** This bug has been marked as a duplicate of bug 197915 ***