General Utility Library for C++17 25.4.1
num_util.h
Go to the documentation of this file.
1
23#ifndef GUL17_NUM_UTIL_H_
24#define GUL17_NUM_UTIL_H_
25
26#include <algorithm>
27#include <cmath>
28#include <limits>
29#include <type_traits>
30
31#include "gul17/internal.h"
32
33namespace gul17 {
34
52template<typename ValueT>
53constexpr auto abs(ValueT n) noexcept -> std::enable_if_t<std::is_unsigned<ValueT>::value, ValueT>
54{
55 return n;
56}
57
61template<typename ValueT>
62constexpr auto abs(ValueT n) noexcept -> std::enable_if_t<not std::is_unsigned<ValueT>::value, ValueT>
63{
64 return std::abs(n);
65}
66
92template<typename NumT, typename OrderT,
93 typename = std::enable_if_t<
94 std::is_arithmetic<NumT>::value
95 and std::is_arithmetic<OrderT>::value
96 >>
97bool within_orders(const NumT a, const NumT b, const OrderT orders) noexcept(false) {
98 // std::pow() is not noexcept, which might or might not be true
99 auto difference = gul17::abs(a - b);
100 if (difference == NumT{ 0 })
101 return true;
102 auto maximum = std::max(gul17::abs(a), gul17::abs(b));
103 auto limit = maximum / std::pow(static_cast<std::decay_t<NumT>>(10.0), orders);
104 return difference < limit;
105}
106
118template<typename NumT>
119bool within_abs(NumT a, NumT b, NumT tol) noexcept {
120 tol = gul17::abs(tol); // Negative diff does not make sense
121 bool ret{};
122 if (a > b) {
123 if (std::is_floating_point<NumT>::value)
124 ret = a - tol <= b; // different formula needed because of inf/-inf and subnormal values
125 else
126 ret = a - b <= tol;
127 } else {
128 if (std::is_floating_point<NumT>::value)
129 ret = b - tol <= a;
130 else
131 ret = b - a <= tol;
132 }
133 return ret;
134}
135
152template<typename NumT,
153 typename = std::enable_if_t<std::is_floating_point<NumT>::value>>
154bool within_ulp(NumT a, NumT b, unsigned int ulp)
155{
156 if (a == b)
157 return true;
158 auto diff = std::abs(a - b);
159 auto maxval = std::max(std::abs(a), std::abs(b));
160
161 // NORMAL cases
162 if (std::isnormal(maxval))
163 {
165 * static_cast<NumT>(ulp) * maxval;
166 }
167
168 // SUBNORMAL cases
169 if (std::isfinite(maxval))
170 return diff <= std::numeric_limits<NumT>::denorm_min() * static_cast<NumT>(ulp);
171
172 // NAN and INF cases: Two NANs or (a xor b is (-)INF) or (INF, -INF pair)
173 return false;
174}
175
207template<class NumT>
208constexpr const NumT& clamp(const NumT& v, const NumT& lo, const NumT& hi) {
209 return std::max(lo, std::min(v, hi)); // usually more optimized than actually using operator<()
210}
234template<class NumT, class Compare>
235constexpr const NumT& clamp(const NumT& v, const NumT& lo, const NumT& hi, Compare comp) {
236 if (comp(v, lo))
237 return lo;
238 if (comp(hi, v))
239 return hi;
240 return v;
241}
242
244
245} // namespace gul17
246
247#endif
248
249// vi:ts=4:sw=4:et
auto constexpr bit_set(unsigned bit) noexcept -> ReturnT
Set a bit in an integral type.
Definition bit_manip.h:121
bool within_ulp(NumT a, NumT b, unsigned int ulp)
Determine if two numbers are almost equal, allowing for a difference of a given number of units-in-th...
Definition num_util.h:154
bool within_orders(const NumT a, const NumT b, const OrderT orders) noexcept(false)
Determine if two numbers are almost equal, comparing only some significant digits.
Definition num_util.h:97
constexpr auto abs(ValueT n) noexcept -> std::enable_if_t< std::is_unsigned< ValueT >::value, ValueT >
Compute the absolute value of a number.
Definition num_util.h:53
constexpr const NumT & clamp(const NumT &v, const NumT &lo, const NumT &hi)
Coerce a value to be within a given range.
Definition num_util.h:208
bool within_abs(NumT a, NumT b, NumT tol) noexcept
Determine if two numbers are almost equal, allowing for an absolute difference.
Definition num_util.h:119
auto maximum(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> DataT
Return the maximum element value in a container.
Definition statistics.h:314
Definition of macros used internally by GUL.
Namespace gul17 contains all functions and classes of the General Utility Library.
Definition doxygen.h:26