the Compartmented Robust Posix C++ Unit Test system

crpcut::abs_diff

Test absolute difference between floating point numbers

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

Verify that |a-b| <= diff. This works well for floating point numbers near 0, but for large numbers crpcut::abs_diff quickly becomes uninteresting. All three parameters must have the same floating point type.

Example: the test program

     
     #include <crpcut.hpp>
     #include <limits>
     
     template <typename T>
     class moving_avg
     {
     public:
       moving_avg() : avg(T()), n(T()) {}
       moving_avg& operator+=(T t) { ++n; avg-= (avg - t)/n; return *this;}
       operator T() const { return avg; }
     private:
       T avg;
       T n;
     };
     
     static const int count = 10;
     
     TEST(too_narrow)
     {
       moving_avg<float> mavg;
       float sum = 0.0;
       for (int n = -count; n < count; ++n)
         {
           sum+= 1.0f/3000 + float(n);
           mavg += 1.0f/3000 + float(n);
         }
       float avg = sum / (2*count);
       float slack = std::numeric_limits<float>::min();
       ASSERT_PRED(crpcut::match<crpcut::abs_diff>(slack), float(mavg), avg);
     }
     
     TEST(close_enough)
     {
       moving_avg<float> mavg;
       float sum = 0.0;
       for (int n = -count; n <= count; ++n)
         {
           sum+= float(n);
           mavg += float(n);
         }
       float avg = sum / (2*count + 1);
       ASSERT_PRED(crpcut::match<crpcut::abs_diff>(1e-6F), float(mavg), avg);
     }
     
     int main(int argc, char *argv[])
     {
       return crpcut::run(argc, argv);
     }

      

fails one test:


     FAILED!: too_narrow
     phase="running"  --------------------------------------------------------------
     samples/abs_diff.cpp:56
     ASSERT_PRED(crpcut::match<crpcut::abs_diff>(slack), float(mavg), avg)
       param1 = -0.499666
       param2 = -0.499667
     for crpcut::match<crpcut::abs_diff>(slack): 
         Max allowed difference is 1.17549e-38
         Actual difference is 1.2517e-06
     
     -------------------------------------------------------------------------------
     ===============================================================================
     2 test cases selected
     
                    Sum   Critical   Non-critical
     PASSED   :       1          1              0
     FAILED   :       1          1              0

      

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