General Utility Library for C++14
2.9

Numerical utility functions.
Functions  
template<typename ValueT >  
constexpr auto  gul14::abs (ValueT n) noexcept > std::enable_if_t< std::is_unsigned< ValueT >::value, ValueT > 
Compute the absolute value of a number. More...  
template<typename NumT , typename OrderT , typename = std::enable_if_t< std::is_arithmetic<NumT>::value and std::is_arithmetic<OrderT>::value >>  
bool  gul14::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. More...  
template<typename NumT >  
bool  gul14::within_abs (NumT a, NumT b, NumT tol) noexcept 
Determine if two numbers are almost equal, allowing for an absolute difference. More...  
template<typename NumT , typename = std::enable_if_t<std::is_floating_point<NumT>::value>>  
bool  gul14::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 unitsinthelastplace (ULPs). More...  
template<class NumT >  
constexpr const NumT &  gul14::clamp (const NumT &v, const NumT &lo, const NumT &hi) 
Coerce a value to be within a given range. More...  
template<class NumT , class Compare >  
constexpr const NumT &  gul14::clamp (const NumT &v, const NumT &lo, const NumT &hi, Compare comp) 
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. More...  

constexprnoexcept 
Compute the absolute value of a number.
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
This function is almost equal to std::abs() with the exception of unsigned integral types, which are returned unchanged and in their original type. This is especially useful in templates, where std::abs() cannot be used for all arithmetic types.
n  The number whose absolute value should be determined. 
Referenced by gul14::gcd(), gul14::lcm(), gul14::remove_outliers(), gul14::within_abs(), gul14::within_orders(), and gul14::within_ulp().

constexpr 
Coerce a value to be within a given range.
Check if value v
is between (including) lo
and hi
. If it is too low, lo
is returned. If it is too high, hi
is returned.
lo
must not be greater than hi
, but they are allowed to be equal.
Only operator<()
is used for this, so it has to be defined for NumT
.
Note that all parameters need to be of the same type. Add the correct suffix if using a literal as shown in the following example:
NumT  Type of the objects to compare. Needs to have operator<() defined. 
v  The value to clamp 
lo  The lower boundary to clamp v to 
hi  The upper boundary to clamp v to 
lo
if v
is less than lo
, a reference to hi
if hi
is less than v
, or a reference to v
otherwise.

constexpr 
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
NumT  Type of the objects to compare. Needs to have operator<() defined. 
Compare  Type of the comparison function. See notes below. 
v  The value to clamp 
lo  The lower boundary to clamp v to 
hi  The upper boundary to clamp v to 
comp  Comparison function object which returns true if the first argument is less than the second. 
The signature of the comparison function should be equivalent to the following:
While the signature does not explicitly require passing the arguments by const reference, the function must not modify the objects passed to it and must be able to accept all values of type (possibly const) Type1
and Type2
regardless of value category. This means that neither Type1 &
nor Type1
are allowed unless a move is equivalent to a copy for Type1
. The types Type1
and Type2
must be such that an object of type T
can be implicitly converted to both of them.

noexcept 
Determine if two numbers are almost equal, allowing for an absolute difference.
All arguments must be the same numeric type (floating point or integer).
a  The first number to compare 
b  The second number to compare 
tol  The absolute tolerance 
References gul14::abs().

noexcept 
Determine if two numbers are almost equal, comparing only some significant digits.
The functions compares the specified number of significant decimal digits of the two values and returns true if they are equal within these digits.
a = 23736384; b = 23736228; within_orders(a, b, 5) => true (first 5 digits equal) a = 23736384; b = 23735384; within_orders(a, b, 5) => false (digit #5 differs)
Unexpected behavior can result when orders is low (< 3) as the simple concept of orders equals digits does not hold so strict anymore.
Remember that any nonzero number has infinite different significant digits compared with 0.00000000. So if one operand is 0.0 while the other is not 0.0 the result must be false.
a  The first number to compare 
b  The second number to compare (same type as a ) 
orders  The number of digits to take for comparison (any numeric type) 
a
and b
are equal or the difference between a
and b
is orders
orders of magnitude lower than the value of a
or b
References gul14::abs(), and gul14::maximum().
bool gul14::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 unitsinthelastplace (ULPs).
One ULP is the spacing between two consecutive floating point representations. There are no possible values in between. Roughly speaking, one ULP is for floating point numbers what the 1 is for integral numbers.
All arguments must be of the same floating point type.
a  The first number to compare 
b  The second number to compare 
ulp  Allowed number of floating point steps in between 
References gul14::abs().