the Compartmented Robust Posix C++ Unit Test system

crpcut::relative_diff

Test relative difference between floating point numbers

Used in: Template parameter to crpcut::match<matcher>(...) in an ASSERT_PRED(pred, ...) check.

Verify that 2*|a-b|/|a+b| <= diff. E.g. if diff=0.01, the values of a and b must not differ by more than 1%. This works well for many floating point values, but is unsuitable for numbers near 0. All three parameters must have the same floating point type.

Example: the test program

     
     #include <crpcut.hpp>
     
     double calc(int iterations)
     {
       double sum = 0.0;
       double d = 1.0;
       while (iterations--)
         {
           sum+=1.0/d;
           d/= 10;
         }
       return sum;
     }
     
     TEST(too_narrow)
     {
       double val = calc(10);
       ASSERT_PRED(crpcut::match<crpcut::relative_diff>(1e-18),
                   val, 1111111111.0);
     }
     
     TEST(close_enough)
     {
       double val = calc(10);
       ASSERT_PRED(crpcut::match<crpcut::relative_diff>(1e-15),
                   val, 1111111111.0);
     }
     
     int main(int argc, char *argv[])
     {
       return crpcut::run(argc, argv);
     }

      

fails one test:


     FAILED!: too_narrow
     phase="running"  --------------------------------------------------------------
     samples/relative_diff.cpp:46
     ASSERT_PRED(crpcut::match<crpcut::relative_diff>(1e-18), val, 1111111111.0)
       param1 = 1.11111e+09
       param2 = 1.11111e+09
     for crpcut::match<crpcut::relative_diff>(1e-18): 
         Max allowed relative difference is 1e-18
         Actual relative difference is 2.14576721212864e-16
     
     -------------------------------------------------------------------------------
     ===============================================================================
     2 test cases selected
     
                    Sum   Critical   Non-critical
     PASSED   :       1          1              0
     FAILED   :       1          1              0

      

See also crpcut::abs_diff and crpcut::ulps_diff for alternative floating point number matching methods.