courtneypresto / googletest

Automatically exported from code.google.com/p/googletest
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

ASSERT_DOUBLE_EQ(0.0, x) fails for 0 < x < std::numeric_limits<double>::epsilon() #208

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I don't intend to use values less than epsilon.  However, when I initialize a 
value to 0.0 the 
system sometimes sets the value to x where 0 < x < epsilon (e.g. x = 
1.88552e-304, epsilon = 
2.22045e-16). 

googletest version: 1.3.0
operating system: Mac OS X 10.5.8

Code, output, and suggested fix below

TEST(Order, gtest_double_eq)
{
    const double ep = std::numeric_limits<double>::epsilon();
    const double rhs = ep / 2;
    ASSERT_TRUE(equals(0.0, rhs));
    std::cout << "rhs: " << rhs << std::endl;
    std::cout << "epsilon: " << ep << std::endl;
    ASSERT_DOUBLE_EQ(0.0, rhs);
}

template<typename Float> 
bool equals(const Float lVal, const Float rVal)
{
    static Float ep = std::numeric_limits<Float>::epsilon();
    const Float diff = fabs(lVal - rVal);
    return diff < ep;
}

TEST(Order, equals)
{
    const double ep = std::numeric_limits<double>::epsilon();
    const double rhs = ep / 2;
    ASSERT_TRUE(equals(0.0, rhs));
}

[ RUN      ] Order.gtest_double_eq
rhs: 1.11022e-16
epsilon: 2.22045e-16
/code/OrderTests.cpp:57: Failure
Value of: rhs
  Actual: 1.1102230246251565e-16
Expected: 0.0
Which is: 0
[  FAILED  ] Order.gtest_double_eq
[ RUN      ] Order.equals
[       OK ] Order.equals

Original issue reported on code.google.com by Jason.S....@gmail.com on 15 Oct 2009 at 7:36

GoogleCodeExporter commented 9 years ago
Jason,

ASSERT_DOUBLE_EQ verifies that the actual number is within 4 ULPs 
(http://en.wikipedia.org/wiki/Unit_in_the_last_place) of expected one (see our 
FP 
macro documentation at 
http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide#Floating-
Point_Comparison). numeric_limits::epsilon is by definition a ULP for 1, but 
you are 
comparing your numbers to 0, and ULP for 0 is much, much smaller so your 
comparison 
fails. What you need is likely ASSERT_NEAR (see the link above).

HTH,
Vlad

Original comment by vladlosev on 20 Oct 2009 at 7:48