ImathFun.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. //
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Copyright Contributors to the OpenEXR Project.
  4. //
  5. #ifndef INCLUDED_IMATHFUN_H
  6. #define INCLUDED_IMATHFUN_H
  7. //-----------------------------------------------------------------------------
  8. //
  9. // Miscellaneous utility functions
  10. //
  11. //-----------------------------------------------------------------------------
  12. #include <limits>
  13. #include <cstdint>
  14. #include "ImathExport.h"
  15. #include "ImathNamespace.h"
  16. #include "ImathPlatform.h"
  17. IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
  18. template <class T>
  19. IMATH_HOSTDEVICE constexpr inline T
  20. abs (T a) IMATH_NOEXCEPT
  21. {
  22. return (a > T (0)) ? a : -a;
  23. }
  24. template <class T>
  25. IMATH_HOSTDEVICE constexpr inline int
  26. sign (T a) IMATH_NOEXCEPT
  27. {
  28. return (a > T (0)) ? 1 : ((a < T (0)) ? -1 : 0);
  29. }
  30. template <class T, class Q>
  31. IMATH_HOSTDEVICE constexpr inline T
  32. lerp (T a, T b, Q t) IMATH_NOEXCEPT
  33. {
  34. return (T) (a * (1 - t) + b * t);
  35. }
  36. template <class T, class Q>
  37. IMATH_HOSTDEVICE constexpr inline T
  38. ulerp (T a, T b, Q t) IMATH_NOEXCEPT
  39. {
  40. return (T) ((a > b) ? (a - (a - b) * t) : (a + (b - a) * t));
  41. }
  42. template <class T>
  43. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T
  44. lerpfactor (T m, T a, T b) IMATH_NOEXCEPT
  45. {
  46. //
  47. // Return how far m is between a and b, that is return t such that
  48. // if:
  49. // t = lerpfactor(m, a, b);
  50. // then:
  51. // m = lerp(a, b, t);
  52. //
  53. // If a==b, return 0.
  54. //
  55. T d = b - a;
  56. T n = m - a;
  57. if (abs (d) > T (1) || abs (n) < std::numeric_limits<T>::max() * abs (d))
  58. return n / d;
  59. return T (0);
  60. }
  61. template <class T>
  62. IMATH_HOSTDEVICE constexpr inline T
  63. clamp (T a, T l, T h) IMATH_NOEXCEPT
  64. {
  65. return (a < l) ? l : ((a > h) ? h : a);
  66. }
  67. template <class T>
  68. IMATH_HOSTDEVICE constexpr inline int
  69. cmp (T a, T b) IMATH_NOEXCEPT
  70. {
  71. return IMATH_INTERNAL_NAMESPACE::sign (a - b);
  72. }
  73. template <class T>
  74. IMATH_HOSTDEVICE constexpr inline int
  75. cmpt (T a, T b, T t) IMATH_NOEXCEPT
  76. {
  77. return (IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t) ? 0 : cmp (a, b);
  78. }
  79. template <class T>
  80. IMATH_HOSTDEVICE constexpr inline bool
  81. iszero (T a, T t) IMATH_NOEXCEPT
  82. {
  83. return (IMATH_INTERNAL_NAMESPACE::abs (a) <= t) ? 1 : 0;
  84. }
  85. template <class T1, class T2, class T3>
  86. IMATH_HOSTDEVICE constexpr inline bool
  87. equal (T1 a, T2 b, T3 t) IMATH_NOEXCEPT
  88. {
  89. return IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t;
  90. }
  91. template <class T>
  92. IMATH_HOSTDEVICE constexpr inline int
  93. floor (T x) IMATH_NOEXCEPT
  94. {
  95. return (x >= 0) ? int (x) : -(int (-x) + (-x > int (-x)));
  96. }
  97. template <class T>
  98. IMATH_HOSTDEVICE constexpr inline int
  99. ceil (T x) IMATH_NOEXCEPT
  100. {
  101. return -floor (-x);
  102. }
  103. template <class T>
  104. IMATH_HOSTDEVICE constexpr inline int
  105. trunc (T x) IMATH_NOEXCEPT
  106. {
  107. return (x >= 0) ? int (x) : -int (-x);
  108. }
  109. //
  110. // Integer division and remainder where the
  111. // remainder of x/y has the same sign as x:
  112. //
  113. // divs(x,y) == (abs(x) / abs(y)) * (sign(x) * sign(y))
  114. // mods(x,y) == x - y * divs(x,y)
  115. //
  116. IMATH_HOSTDEVICE constexpr inline int
  117. divs (int x, int y) IMATH_NOEXCEPT
  118. {
  119. return (x >= 0) ? ((y >= 0) ? (x / y) : -(x / -y)) : ((y >= 0) ? -(-x / y) : (-x / -y));
  120. }
  121. IMATH_HOSTDEVICE constexpr inline int
  122. mods (int x, int y) IMATH_NOEXCEPT
  123. {
  124. return (x >= 0) ? ((y >= 0) ? (x % y) : (x % -y)) : ((y >= 0) ? -(-x % y) : -(-x % -y));
  125. }
  126. //
  127. // Integer division and remainder where the
  128. // remainder of x/y is always positive:
  129. //
  130. // divp(x,y) == floor (double(x) / double (y))
  131. // modp(x,y) == x - y * divp(x,y)
  132. //
  133. IMATH_HOSTDEVICE constexpr inline int
  134. divp (int x, int y) IMATH_NOEXCEPT
  135. {
  136. return (x >= 0) ? ((y >= 0) ? (x / y) : -(x / -y))
  137. : ((y >= 0) ? -((y - 1 - x) / y) : ((-y - 1 - x) / -y));
  138. }
  139. IMATH_HOSTDEVICE constexpr inline int
  140. modp (int x, int y) IMATH_NOEXCEPT
  141. {
  142. return x - y * divp (x, y);
  143. }
  144. //----------------------------------------------------------
  145. // Successor and predecessor for floating-point numbers:
  146. //
  147. // succf(f) returns float(f+e), where e is the smallest
  148. // positive number such that float(f+e) != f.
  149. //
  150. // predf(f) returns float(f-e), where e is the smallest
  151. // positive number such that float(f-e) != f.
  152. //
  153. // succd(d) returns double(d+e), where e is the smallest
  154. // positive number such that double(d+e) != d.
  155. //
  156. // predd(d) returns double(d-e), where e is the smallest
  157. // positive number such that double(d-e) != d.
  158. //
  159. // Exceptions: If the input value is an infinity or a nan,
  160. // succf(), predf(), succd(), and predd() all
  161. // return the input value without changing it.
  162. //
  163. //----------------------------------------------------------
  164. IMATH_EXPORT float succf (float f) IMATH_NOEXCEPT;
  165. IMATH_EXPORT float predf (float f) IMATH_NOEXCEPT;
  166. IMATH_EXPORT double succd (double d) IMATH_NOEXCEPT;
  167. IMATH_EXPORT double predd (double d) IMATH_NOEXCEPT;
  168. //
  169. // Return true if the number is not a NaN or Infinity.
  170. //
  171. IMATH_HOSTDEVICE inline bool
  172. finitef (float f) IMATH_NOEXCEPT
  173. {
  174. union
  175. {
  176. float f;
  177. int i;
  178. } u;
  179. u.f = f;
  180. return (u.i & 0x7f800000) != 0x7f800000;
  181. }
  182. IMATH_HOSTDEVICE inline bool
  183. finited (double d) IMATH_NOEXCEPT
  184. {
  185. union
  186. {
  187. double d;
  188. uint64_t i;
  189. } u;
  190. u.d = d;
  191. return (u.i & 0x7ff0000000000000LL) != 0x7ff0000000000000LL;
  192. }
  193. IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
  194. #endif // INCLUDED_IMATHFUN_H