Advertisement
Tainel

src/base/features/compare.hpp

Jun 4th, 2023 (edited)
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.75 KB | Source Code | 0 0
  1. #pragma once
  2.  
  3. #include"base/dependencies/index.hpp"
  4.  
  5. #include"floats.hpp"
  6. #include"metaprogramming.hpp"
  7.  
  8. // Default epsilon constants for each floating point type alias.
  9. template<Float Real>constexpr Real epsilon;
  10. template<>constexpr f32 epsilon<f32>{1e-5F};
  11. template<>constexpr f64 epsilon<f64>{1e-7};
  12. template<>constexpr f80 epsilon<f80>{1e-10L};
  13.  
  14. // Return the real `m` such that `a` and `b` are considered approximately equal
  15. // iff their difference is no more than `m`.
  16. template<Float Real,Real Eps=epsilon<Real>>
  17. Real margin(Real const a,Real const b){
  18.     static_assert(numeric_limits<Real>::epsilon()<=Eps&&Eps<1);
  19.     return max({abs(a),abs(b),Real(1)})*Eps;
  20. }
  21.  
  22. // Floating point equality comparison functor.
  23. template<Float Real=f64,Real Eps=epsilon<Real>>struct real_eq{
  24.     // Determine if `a` is approximately equal to `b`.
  25.     bool operator()(Real const a,Real const b)const{
  26.         return abs(a-b)<=margin<Real,Eps>(a,b);
  27.     }
  28. };
  29.  
  30. // Floating point inequality comparison functor.
  31. template<Float Real=f64,Real Eps=epsilon<Real>>struct real_ne{
  32.     // Determine if `a` is definitely different from `b`.
  33.     bool operator()(Real const a,Real const b)const{
  34.         return!real_eq<Real,Eps>{}(a,b);
  35.     }
  36. };
  37.  
  38. // Floating point strict order comparison functor.
  39. template<Float Real=f64,Real Eps=epsilon<Real>>struct real_lt{
  40.     // Determine if `a` is definitely less than `b`.
  41.     bool operator()(Real const a,Real const b)const{
  42.         return a+margin<Real,Eps>(a,b)<b;
  43.     }
  44. };
  45.  
  46. // Floating point non-strict order comparison functor.
  47. template<Float Real=f64,Real Eps=epsilon<Real>>struct real_le{
  48.     // Determine if `a` is definitely less than or approximately equal to `b`.
  49.     bool operator()(Real const a,Real const b)const{
  50.         return a<=b+margin<Real,Eps>(a,b);
  51.     }
  52. };
  53.  
  54. // Floating point reverse strict order comparison functor.
  55. template<Float Real=f64,Real Eps=epsilon<Real>>struct real_gt{
  56.     // Determine if `a` is definitely greater than `b`.
  57.     bool operator()(Real const a,Real const b)const{
  58.         return real_lt<Real,Eps>{}(b,a);
  59.     }
  60. };
  61.  
  62. // Floating point reverse non-strict order comparison functor.
  63. template<Float Real=f64,Real Eps=epsilon<Real>>struct real_ge{
  64.     // Determine if `a` is definitely greater than or approximately equal to `b`.
  65.     bool operator()(Real const a,Real const b)const{
  66.         return real_le<Real,Eps>{}(b,a);
  67.     }
  68. };
  69.  
  70. // Minimum functor.
  71. template<class Type>struct minimum{
  72.     // Return the minimum of two objects. Only one comparison is performed.
  73.     Type const&operator()(Type const&lhs,Type const&rhs)const{
  74.         return min(lhs,rhs);
  75.     }
  76. };
  77.  
  78. // Maximum functor.
  79. template<class Type>struct maximum{
  80.     // Return the maximum of two objects. Only one comparison is performed.
  81.     Type const&operator()(Type const&lhs,Type const&rhs)const{
  82.         return max(lhs,rhs);
  83.     }
  84. };
  85.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement