mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-21 02:43:33 +08:00
Make wrap() work with integer types (#145)
* Make wrap() work with integers
This commit is contained in:
+50
-11
@@ -39,25 +39,64 @@ bool isEqualF(const Type x, const Type y, const Type eps = 1e-4f)
|
||||
|| (isinf(x) && isinf(y) && isnan(x - y));
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename Floating>
|
||||
Floating wrap_floating(Floating x, Floating low, Floating high) {
|
||||
// already in range
|
||||
if (low <= x && x < high) {
|
||||
return x;
|
||||
}
|
||||
|
||||
const auto range = high - low;
|
||||
const auto inv_range = Floating(1) / range; // should evaluate at compile time, multiplies below at runtime
|
||||
const auto num_wraps = floor((x - low) * inv_range);
|
||||
return x - range * num_wraps;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* Wrap value to stay in range [low, high)
|
||||
* Wrap single precision floating point value to stay in range [low, high)
|
||||
*
|
||||
* @param x input possibly outside of the range
|
||||
* @param low lower limit of the allowed range
|
||||
* @param high upper limit of the allowed range
|
||||
* @return wrapped value inside the range
|
||||
*/
|
||||
template<typename Type>
|
||||
Type wrap(Type x, Type low, Type high) {
|
||||
// already in range
|
||||
if (low <= x && x < high) {
|
||||
return x;
|
||||
}
|
||||
float wrap(float x, float low, float high) {
|
||||
return matrix::detail::wrap_floating(x, low, high);
|
||||
}
|
||||
|
||||
const Type range = high - low;
|
||||
const Type inv_range = Type(1) / range; // should evaluate at compile time, multiplies below at runtime
|
||||
const Type num_wraps = floor((x - low) * inv_range);
|
||||
return x - range * num_wraps;
|
||||
/**
|
||||
* Wrap double precision floating point value to stay in range [low, high)
|
||||
*
|
||||
* @param x input possibly outside of the range
|
||||
* @param low lower limit of the allowed range
|
||||
* @param high upper limit of the allowed range
|
||||
* @return wrapped value inside the range
|
||||
*/
|
||||
double wrap(double x, double low, double high) {
|
||||
return matrix::detail::wrap_floating(x, low, high);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap integer value to stay in range [low, high)
|
||||
*
|
||||
* @param x input possibly outside of the range
|
||||
* @param low lower limit of the allowed range
|
||||
* @param high upper limit of the allowed range
|
||||
* @return wrapped value inside the range
|
||||
*/
|
||||
template<typename Integer>
|
||||
Integer wrap(Integer x, Integer low, Integer high) {
|
||||
const auto range = high - low;
|
||||
|
||||
if (x < low)
|
||||
x += range * ((low - x) / range + 1);
|
||||
|
||||
return low + (x - low) % range;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user