Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include"base/dependencies/index.hpp"
- #include"floats.hpp"
- #include"metaprogramming.hpp"
- // Default epsilon constants for each floating point type alias.
- template<Float Real>constexpr Real epsilon;
- template<>constexpr f32 epsilon<f32>{1e-5F};
- template<>constexpr f64 epsilon<f64>{1e-7};
- template<>constexpr f80 epsilon<f80>{1e-10L};
- // Return the real `m` such that `a` and `b` are considered approximately equal
- // iff their difference is no more than `m`.
- template<Float Real,Real Eps=epsilon<Real>>
- Real margin(Real const a,Real const b){
- static_assert(numeric_limits<Real>::epsilon()<=Eps&&Eps<1);
- return max({abs(a),abs(b),Real(1)})*Eps;
- }
- // Floating point equality comparison functor.
- template<Float Real=f64,Real Eps=epsilon<Real>>struct real_eq{
- // Determine if `a` is approximately equal to `b`.
- bool operator()(Real const a,Real const b)const{
- return abs(a-b)<=margin<Real,Eps>(a,b);
- }
- };
- // Floating point inequality comparison functor.
- template<Float Real=f64,Real Eps=epsilon<Real>>struct real_ne{
- // Determine if `a` is definitely different from `b`.
- bool operator()(Real const a,Real const b)const{
- return!real_eq<Real,Eps>{}(a,b);
- }
- };
- // Floating point strict order comparison functor.
- template<Float Real=f64,Real Eps=epsilon<Real>>struct real_lt{
- // Determine if `a` is definitely less than `b`.
- bool operator()(Real const a,Real const b)const{
- return a+margin<Real,Eps>(a,b)<b;
- }
- };
- // Floating point non-strict order comparison functor.
- template<Float Real=f64,Real Eps=epsilon<Real>>struct real_le{
- // Determine if `a` is definitely less than or approximately equal to `b`.
- bool operator()(Real const a,Real const b)const{
- return a<=b+margin<Real,Eps>(a,b);
- }
- };
- // Floating point reverse strict order comparison functor.
- template<Float Real=f64,Real Eps=epsilon<Real>>struct real_gt{
- // Determine if `a` is definitely greater than `b`.
- bool operator()(Real const a,Real const b)const{
- return real_lt<Real,Eps>{}(b,a);
- }
- };
- // Floating point reverse non-strict order comparison functor.
- template<Float Real=f64,Real Eps=epsilon<Real>>struct real_ge{
- // Determine if `a` is definitely greater than or approximately equal to `b`.
- bool operator()(Real const a,Real const b)const{
- return real_le<Real,Eps>{}(b,a);
- }
- };
- // Minimum functor.
- template<class Type>struct minimum{
- // Return the minimum of two objects. Only one comparison is performed.
- Type const&operator()(Type const&lhs,Type const&rhs)const{
- return min(lhs,rhs);
- }
- };
- // Maximum functor.
- template<class Type>struct maximum{
- // Return the maximum of two objects. Only one comparison is performed.
- Type const&operator()(Type const&lhs,Type const&rhs)const{
- return max(lhs,rhs);
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement