integer.inl 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /// @ref gtx_integer
  2. namespace glm
  3. {
  4. // pow
  5. GLM_FUNC_QUALIFIER int pow(int x, uint y)
  6. {
  7. if(y == 0)
  8. return x >= 0 ? 1 : -1;
  9. int result = x;
  10. for(uint i = 1; i < y; ++i)
  11. result *= x;
  12. return result;
  13. }
  14. // sqrt: From Christopher J. Musial, An integer square root, Graphics Gems, 1990, page 387
  15. GLM_FUNC_QUALIFIER int sqrt(int x)
  16. {
  17. if(x <= 1) return x;
  18. int NextTrial = x >> 1;
  19. int CurrentAnswer;
  20. do
  21. {
  22. CurrentAnswer = NextTrial;
  23. NextTrial = (NextTrial + x / NextTrial) >> 1;
  24. } while(NextTrial < CurrentAnswer);
  25. return CurrentAnswer;
  26. }
  27. // Henry Gordon Dietz: http://aggregate.org/MAGIC/
  28. namespace detail
  29. {
  30. GLM_FUNC_QUALIFIER unsigned int ones32(unsigned int x)
  31. {
  32. /* 32-bit recursive reduction using SWAR...
  33. but first step is mapping 2-bit values
  34. into sum of 2 1-bit values in sneaky way
  35. */
  36. x -= ((x >> 1) & 0x55555555);
  37. x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
  38. x = (((x >> 4) + x) & 0x0f0f0f0f);
  39. x += (x >> 8);
  40. x += (x >> 16);
  41. return(x & 0x0000003f);
  42. }
  43. }//namespace detail
  44. // Henry Gordon Dietz: http://aggregate.org/MAGIC/
  45. /*
  46. GLM_FUNC_QUALIFIER unsigned int floor_log2(unsigned int x)
  47. {
  48. x |= (x >> 1);
  49. x |= (x >> 2);
  50. x |= (x >> 4);
  51. x |= (x >> 8);
  52. x |= (x >> 16);
  53. return _detail::ones32(x) >> 1;
  54. }
  55. */
  56. // mod
  57. GLM_FUNC_QUALIFIER int mod(int x, int y)
  58. {
  59. return ((x % y) + y) % y;
  60. }
  61. // factorial (!12 max, integer only)
  62. template<typename genType>
  63. GLM_FUNC_QUALIFIER genType factorial(genType const& x)
  64. {
  65. genType Temp = x;
  66. genType Result;
  67. for(Result = 1; Temp > 1; --Temp)
  68. Result *= Temp;
  69. return Result;
  70. }
  71. template<typename T, qualifier Q>
  72. GLM_FUNC_QUALIFIER vec<2, T, Q> factorial(
  73. vec<2, T, Q> const& x)
  74. {
  75. return vec<2, T, Q>(
  76. factorial(x.x),
  77. factorial(x.y));
  78. }
  79. template<typename T, qualifier Q>
  80. GLM_FUNC_QUALIFIER vec<3, T, Q> factorial(
  81. vec<3, T, Q> const& x)
  82. {
  83. return vec<3, T, Q>(
  84. factorial(x.x),
  85. factorial(x.y),
  86. factorial(x.z));
  87. }
  88. template<typename T, qualifier Q>
  89. GLM_FUNC_QUALIFIER vec<4, T, Q> factorial(
  90. vec<4, T, Q> const& x)
  91. {
  92. return vec<4, T, Q>(
  93. factorial(x.x),
  94. factorial(x.y),
  95. factorial(x.z),
  96. factorial(x.w));
  97. }
  98. GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
  99. {
  100. if (y == 0)
  101. return 1u;
  102. uint result = x;
  103. for(uint i = 1; i < y; ++i)
  104. result *= x;
  105. return result;
  106. }
  107. GLM_FUNC_QUALIFIER uint sqrt(uint x)
  108. {
  109. if(x <= 1) return x;
  110. uint NextTrial = x >> 1;
  111. uint CurrentAnswer;
  112. do
  113. {
  114. CurrentAnswer = NextTrial;
  115. NextTrial = (NextTrial + x / NextTrial) >> 1;
  116. } while(NextTrial < CurrentAnswer);
  117. return CurrentAnswer;
  118. }
  119. GLM_FUNC_QUALIFIER uint mod(uint x, uint y)
  120. {
  121. return x - y * (x / y);
  122. }
  123. #if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC))
  124. GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x)
  125. {
  126. return 31u - findMSB(x);
  127. }
  128. #else
  129. // Hackers Delight: http://www.hackersdelight.org/HDcode/nlz.c.txt
  130. GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x)
  131. {
  132. int y, m, n;
  133. y = -int(x >> 16); // If left half of x is 0,
  134. m = (y >> 16) & 16; // set n = 16. If left half
  135. n = 16 - m; // is nonzero, set n = 0 and
  136. x = x >> m; // shift x right 16.
  137. // Now x is of the form 0000xxxx.
  138. y = x - 0x100; // If positions 8-15 are 0,
  139. m = (y >> 16) & 8; // add 8 to n and shift x left 8.
  140. n = n + m;
  141. x = x << m;
  142. y = x - 0x1000; // If positions 12-15 are 0,
  143. m = (y >> 16) & 4; // add 4 to n and shift x left 4.
  144. n = n + m;
  145. x = x << m;
  146. y = x - 0x4000; // If positions 14-15 are 0,
  147. m = (y >> 16) & 2; // add 2 to n and shift x left 2.
  148. n = n + m;
  149. x = x << m;
  150. y = x >> 14; // Set y = 0, 1, 2, or 3.
  151. m = y & ~(y >> 1); // Set m = 0, 1, 2, or 2 resp.
  152. return unsigned(n + 2 - m);
  153. }
  154. #endif//(GLM_COMPILER)
  155. }//namespace glm