-
Notifications
You must be signed in to change notification settings - Fork 0
/
floating_point_compare.h
36 lines (29 loc) · 1.13 KB
/
floating_point_compare.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#ifndef FLOATING_POINT_COMPARE_H
#define FLOATING_POINT_COMPARE_H
#include <cmath>
#include <type_traits>
#include <limits>
namespace detail
{
template<class T, int precission>
struct delimiter
{
static constexpr T value = std::pow<T>(static_cast<T>(0.1), precission);
};
}
template<int precission, class Left, class Right>
constexpr bool floating_point_compare(const Left &left, const Right &right)
{
using common_type = typename std::common_type<Left, Right>::type;
static_assert(std::is_floating_point<common_type>::value, "Only floating point types");
return std::abs(left - right) < detail::delimiter<common_type, precission>::value;
}
template<class Left, class Right>
constexpr bool floating_point_compare(const Left &left, const Right &right)
{
using common_type = typename std::common_type<Left, Right>::type;
static_assert(std::is_floating_point<common_type>::value, "Only floating point types");
return std::abs(left - right) < std::numeric_limits<common_type>::epsilon() * std::abs(left - right) * 2
|| std::abs(left - right) < std::numeric_limits<common_type>::min();
}
#endif // FLOATING_POINT_COMPARE_H