Most efficient/elegant way to clip a number?
What about boring, old, readable, and shortest yet:
float clip(float n, float lower, float upper) {
return std::max(lower, std::min(n, upper));
}
?
This expression could also be 'genericized' like so:
template <typename T>
T clip(const T& n, const T& lower, const T& upper) {
return std::max(lower, std::min(n, upper));
}
Update
Billy ONeal added:
Note that on windows you might have to define NOMINMAX because they define min and max macros which conflict
Why rewrite something that's already been written for you?
#include <boost/algorithm/clamp.hpp>
boost::algorithm::clamp(n, lower, upper);
As of C++17, this is now part of the STL:
#include <algorithm>
std::clamp(n, lower, upper);
C++17 is expected to add a clamp function. Courtesy of cppreference.com:
template<class T>
constexpr const T& clamp( const T& v, const T& lo, const T& hi );
template<class T, class Compare>
constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp );
UPDATE: C++17's <algorithm>
header added std::clamp(value, low, high)
.
In older C++ versions, I'd very rarely go beyond...
return n <= lower ? lower : n >= upper ? upper : n;
...or, if you find it more readable keeping the left-to-right ordering of lower, n and upper...
return n <= lower ? lower : n <= upper ? n : upper;
...or...
return lower >= n ? lower : n <= upper ? n : upper;
(using <=
, >=
is faster than <
, >
because when the terms are equal it avoids further comparisons)
If you know you might have them, you'd want to check if NaN / Inf etc. are preserved....
I say rarely and not never just because sometimes less branching can be faster, but if you or other people you work with are likely to find the code for that cryptic, it's best avoided unless it's in performance-critical code and profiling shows it matters.