General Utility Library for C++17 26.5.0
num_util.h
Go to the documentation of this file.
1
26#ifndef GUL17_NUM_UTIL_H_
27#define GUL17_NUM_UTIL_H_
28
29#include <algorithm>
30#include <cmath>
31#include <limits>
32#include <type_traits>
33
34#include "gul17/internal.h"
35
36namespace gul17 {
37
55template<typename ValueT>
56constexpr auto abs(ValueT n) noexcept -> std::enable_if_t<std::is_unsigned<ValueT>::value, ValueT>
57{
58 return n;
59}
60
64template<typename ValueT>
65constexpr auto abs(ValueT n) noexcept -> std::enable_if_t<not std::is_unsigned<ValueT>::value, ValueT>
66{
67 return std::abs(n);
68}
69
95template<typename NumT, typename OrderT,
96 typename = std::enable_if_t<
97 std::is_arithmetic<NumT>::value
98 and std::is_arithmetic<OrderT>::value
99 >>
100bool within_orders(const NumT a, const NumT b, const OrderT orders) noexcept(false) {
101 // std::pow() is not noexcept, which might or might not be true
102 auto difference = gul17::abs(a - b);
103 if (difference == NumT{ 0 })
104 return true;
105 auto maximum = std::max(gul17::abs(a), gul17::abs(b));
106 auto limit = maximum / std::pow(static_cast<std::decay_t<NumT>>(10.0), orders);
107 return difference < limit;
108}
109
121template<typename NumT>
122bool within_abs(NumT a, NumT b, NumT tol) noexcept {
123 tol = gul17::abs(tol); // Negative diff does not make sense
124 bool ret{};
125 if (a > b) {
126 if (std::is_floating_point<NumT>::value)
127 ret = a - tol <= b; // different formula needed because of inf/-inf and subnormal values
128 else
129 ret = a - b <= tol;
130 } else {
131 if (std::is_floating_point<NumT>::value)
132 ret = b - tol <= a;
133 else
134 ret = b - a <= tol;
135 }
136 return ret;
137}
138
155template<typename NumT,
156 typename = std::enable_if_t<std::is_floating_point<NumT>::value>>
157bool within_ulp(NumT a, NumT b, unsigned int ulp)
158{
159 if (a == b)
160 return true;
161 auto diff = std::abs(a - b);
162 auto maxval = std::max(std::abs(a), std::abs(b));
163
164 // NORMAL cases
165 if (std::isnormal(maxval))
166 {
168 * static_cast<NumT>(ulp) * maxval;
169 }
170
171 // SUBNORMAL cases
172 if (std::isfinite(maxval))
173 return diff <= std::numeric_limits<NumT>::denorm_min() * static_cast<NumT>(ulp);
174
175 // NAN and INF cases: Two NANs or (a xor b is (-)INF) or (INF, -INF pair)
176 return false;
177}
178
210template<class NumT>
211constexpr const NumT& clamp(const NumT& v, const NumT& lo, const NumT& hi) {
212 return std::max(lo, std::min(v, hi)); // usually more optimized than actually using operator<()
213}
237template<class NumT, class Compare>
238constexpr const NumT& clamp(const NumT& v, const NumT& lo, const NumT& hi, Compare comp) {
239 if (comp(v, lo))
240 return lo;
241 if (comp(hi, v))
242 return hi;
243 return v;
244}
245
247
248} // namespace gul17
249
250#endif
251
252// 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:124
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:157
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:100
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:56
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:211
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:122
auto maximum(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> DataT
Return the maximum element value in a container.
Definition statistics.h:317
Definition of macros used internally by GUL.
Namespace gul17 contains all functions and classes of the General Utility Library.
Definition doxygen.h:29