
On 08/21/2011 04:19 PM, Michel MORIN wrote:
The Units' test (libs/units/test/test_trig.cpp) fails on Sandia-darwin-4.4: http://tinyurl.com/3wherck
The failure is caused by the fact that the results of `std::acos(0.2)` and `std::acos(d)` (double d = 0.2) are NOT equal on Sandia-darwin-4.4.
On gcc-4.3 and newer versions, built-in math functions having constant arguments are evaluated at compile time using the MPFR (Multiple Precision Floating-Point Reliable) library. This happens even if optimization is disabled.
So, the results of std::acos(0.2); // evaluated by the MPFR library at compile time and double d = 0.2; std::acos(d); // evaluated by the built-in function at run time are different. (If we compile with optimization enabled, the latter code is also evaluated by the MPFR library at compile time.)
The solution to this problem is * Change BOOST_CHECK_EQUAL to BOOST_CHECK_CLOSE_FRACTION. or * Change `std::acos(0.2)` to `std::acos(d)` (with `double d = 0.2`)
An interesting thing is that the test fails only on Sandia-darwin (x86-64) platform. On other platforms using gcc 4.3-4.6, the test runs successfully. I suspect that they have 80-bit registers and so the result of `std::acos(d)` is as accurate as the result of the MPFR library. Do you have any thoughts about this?
This seems correct. The compile-time evaluation of GCC yields correctly-rounded results, which is not the case of the runtime evaluation. I don't know what BOOST_CHECK_CLOSE_FRACTION does, but I don't think there is any guarantee at all about the accuracy of the standard mathematical functions.