VCCC  2024.05
VisualCamp Common C++ library
float_equal.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2023/10/25.
3 //
4 
5 #ifndef VCCC_NUMERIC_FLOAT_EQUAL_HPP
6 #define VCCC_NUMERIC_FLOAT_EQUAL_HPP
7 
8 #include <algorithm>
9 #include <cmath>
10 #include <limits>
11 #include <type_traits>
12 
13 #include "vccc/__math/epsilon.hpp"
14 
15 namespace vccc {
16 
24 namespace detail {
25 
26 template<typename T, bool v = std::numeric_limits<T>::is_exact>
27 struct float_equal_to_impl;
28 
29 template<typename T>
30 struct float_equal_to_impl<T, true> {
31  constexpr inline bool operator()(const T& a, const T& b, const T&) const {
32  return a == b;
33  }
34 };
35 
36 template<typename T>
37 struct float_equal_to_impl<T, false> {
38  constexpr inline bool operator()(const T& a, const T& b, const T& e) const {
39  return compare_positive(std::abs(a), std::abs(b), std::abs(a - b), e);
40  }
41 
42  private:
43  constexpr inline bool compare_positive(const T& a, const T& b, const T& diff, const T& e) const {
44  return (a <= e && b <= e) || diff <= (std::min)(a, b) * e;
45  }
46 };
47 
48 } // namespace detail
49 
55 template<typename T = void>
57  constexpr inline bool operator()(const T& a, const T& b, const T& e = vccc::epsilon<T>()) const {
58  return detail::float_equal_to_impl<T>{}(a, b, e);
59  }
60 };
61 
62 
69 template<>
70 struct float_equal_to<void> {
71  template<typename T, typename U, typename E = std::common_type_t<T, U>>
72  constexpr inline auto operator()(const T& a, const U& b, const E& e = vccc::epsilon<E>()) const
73  -> decltype(std::declval<float_equal_to<std::common_type_t<T, U, E>>&>()(std::declval<const T&>(), std::declval<const U&>(), std::declval<const E&>()))
74  {
75  using C = std::common_type_t<T, U, E>;
76  return float_equal_to<C>{}(static_cast<C>(a), static_cast<C>(b), static_cast<C>(e));
77  }
78 };
79 
81 
100 template<typename T, typename U, typename E = std::common_type_t<T, U>>
101 constexpr inline bool
102 float_equal(const T& a, const U& b, const E& epsilon = vccc::epsilon<E>()) {
103  using C = std::common_type_t<T, U, E>;
104  return float_equal_to<C>{}(static_cast<C>(a), static_cast<C>(b), static_cast<C>(epsilon));
105 }
106 
108 
109 } // namespace vccc
110 
111 #endif // VCCC_NUMERIC_FLOAT_EQUAL_HPP
constexpr VCCC_INLINE_OR_STATIC detail::min_niebloid min
Definition: min.hpp:90
constexpr T e
the mathematical constant
Definition: constants.hpp:37
T epsilon()
Get machine epsilon for the given type.
Definition: epsilon.hpp:32
constexpr bool float_equal(const T &a, const U &b, const E &epsilon=vccc::epsilon< E >())
Compare if two floating-points are approximately equal.
Definition: float_equal.hpp:102
typename common_type< T... >::type common_type_t
Definition: common_type.hpp:229
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr auto operator()(const T &a, const U &b, const E &e=vccc::epsilon< E >()) const -> decltype(std::declval< float_equal_to< std::common_type_t< T, U, E >> & >()(std::declval< const T & >(), std::declval< const U & >(), std::declval< const E & >()))
Definition: float_equal.hpp:72
function object implementing approximately equal of x and y
Definition: float_equal.hpp:56
constexpr bool operator()(const T &a, const T &b, const T &e=vccc::epsilon< T >()) const
Definition: float_equal.hpp:57