// // SPDX-License-Identifier: BSD-3-Clause // Copyright Contributors to the OpenEXR Project. // #ifndef INCLUDED_IMATHFUN_H #define INCLUDED_IMATHFUN_H //----------------------------------------------------------------------------- // // Miscellaneous utility functions // //----------------------------------------------------------------------------- #include #include #include "ImathExport.h" #include "ImathNamespace.h" #include "ImathPlatform.h" IMATH_INTERNAL_NAMESPACE_HEADER_ENTER template IMATH_HOSTDEVICE constexpr inline T abs (T a) IMATH_NOEXCEPT { return (a > T (0)) ? a : -a; } template IMATH_HOSTDEVICE constexpr inline int sign (T a) IMATH_NOEXCEPT { return (a > T (0)) ? 1 : ((a < T (0)) ? -1 : 0); } template IMATH_HOSTDEVICE constexpr inline T lerp (T a, T b, Q t) IMATH_NOEXCEPT { return (T) (a * (1 - t) + b * t); } template IMATH_HOSTDEVICE constexpr inline T ulerp (T a, T b, Q t) IMATH_NOEXCEPT { return (T) ((a > b) ? (a - (a - b) * t) : (a + (b - a) * t)); } template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T lerpfactor (T m, T a, T b) IMATH_NOEXCEPT { // // Return how far m is between a and b, that is return t such that // if: // t = lerpfactor(m, a, b); // then: // m = lerp(a, b, t); // // If a==b, return 0. // T d = b - a; T n = m - a; if (abs (d) > T (1) || abs (n) < std::numeric_limits::max() * abs (d)) return n / d; return T (0); } template IMATH_HOSTDEVICE constexpr inline T clamp (T a, T l, T h) IMATH_NOEXCEPT { return (a < l) ? l : ((a > h) ? h : a); } template IMATH_HOSTDEVICE constexpr inline int cmp (T a, T b) IMATH_NOEXCEPT { return IMATH_INTERNAL_NAMESPACE::sign (a - b); } template IMATH_HOSTDEVICE constexpr inline int cmpt (T a, T b, T t) IMATH_NOEXCEPT { return (IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t) ? 0 : cmp (a, b); } template IMATH_HOSTDEVICE constexpr inline bool iszero (T a, T t) IMATH_NOEXCEPT { return (IMATH_INTERNAL_NAMESPACE::abs (a) <= t) ? 1 : 0; } template IMATH_HOSTDEVICE constexpr inline bool equal (T1 a, T2 b, T3 t) IMATH_NOEXCEPT { return IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t; } template IMATH_HOSTDEVICE constexpr inline int floor (T x) IMATH_NOEXCEPT { return (x >= 0) ? int (x) : -(int (-x) + (-x > int (-x))); } template IMATH_HOSTDEVICE constexpr inline int ceil (T x) IMATH_NOEXCEPT { return -floor (-x); } template IMATH_HOSTDEVICE constexpr inline int trunc (T x) IMATH_NOEXCEPT { return (x >= 0) ? int (x) : -int (-x); } // // Integer division and remainder where the // remainder of x/y has the same sign as x: // // divs(x,y) == (abs(x) / abs(y)) * (sign(x) * sign(y)) // mods(x,y) == x - y * divs(x,y) // IMATH_HOSTDEVICE constexpr inline int divs (int x, int y) IMATH_NOEXCEPT { return (x >= 0) ? ((y >= 0) ? (x / y) : -(x / -y)) : ((y >= 0) ? -(-x / y) : (-x / -y)); } IMATH_HOSTDEVICE constexpr inline int mods (int x, int y) IMATH_NOEXCEPT { return (x >= 0) ? ((y >= 0) ? (x % y) : (x % -y)) : ((y >= 0) ? -(-x % y) : -(-x % -y)); } // // Integer division and remainder where the // remainder of x/y is always positive: // // divp(x,y) == floor (double(x) / double (y)) // modp(x,y) == x - y * divp(x,y) // IMATH_HOSTDEVICE constexpr inline int divp (int x, int y) IMATH_NOEXCEPT { return (x >= 0) ? ((y >= 0) ? (x / y) : -(x / -y)) : ((y >= 0) ? -((y - 1 - x) / y) : ((-y - 1 - x) / -y)); } IMATH_HOSTDEVICE constexpr inline int modp (int x, int y) IMATH_NOEXCEPT { return x - y * divp (x, y); } //---------------------------------------------------------- // Successor and predecessor for floating-point numbers: // // succf(f) returns float(f+e), where e is the smallest // positive number such that float(f+e) != f. // // predf(f) returns float(f-e), where e is the smallest // positive number such that float(f-e) != f. // // succd(d) returns double(d+e), where e is the smallest // positive number such that double(d+e) != d. // // predd(d) returns double(d-e), where e is the smallest // positive number such that double(d-e) != d. // // Exceptions: If the input value is an infinity or a nan, // succf(), predf(), succd(), and predd() all // return the input value without changing it. // //---------------------------------------------------------- IMATH_EXPORT float succf (float f) IMATH_NOEXCEPT; IMATH_EXPORT float predf (float f) IMATH_NOEXCEPT; IMATH_EXPORT double succd (double d) IMATH_NOEXCEPT; IMATH_EXPORT double predd (double d) IMATH_NOEXCEPT; // // Return true if the number is not a NaN or Infinity. // IMATH_HOSTDEVICE inline bool finitef (float f) IMATH_NOEXCEPT { union { float f; int i; } u; u.f = f; return (u.i & 0x7f800000) != 0x7f800000; } IMATH_HOSTDEVICE inline bool finited (double d) IMATH_NOEXCEPT { union { double d; uint64_t i; } u; u.d = d; return (u.i & 0x7ff0000000000000LL) != 0x7ff0000000000000LL; } IMATH_INTERNAL_NAMESPACE_HEADER_EXIT #endif // INCLUDED_IMATHFUN_H