1 /////////////////////////////////////////////////////////////////////////////////////////////////// 2 // OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) 3 /////////////////////////////////////////////////////////////////////////////////////////////////// 4 // Created : 2005-12-24 5 // Updated : 2011-10-13 6 // Licence : This source is under MIT License 7 // File : glm/gtx/integer.inl 8 /////////////////////////////////////////////////////////////////////////////////////////////////// 9 10 namespace glm 11 { 12 // pow 13 GLM_FUNC_QUALIFIER int pow(int x, int y) 14 { 15 if(y == 0) 16 return 1; 17 int result = x; 18 for(int i = 1; i < y; ++i) 19 result *= x; 20 return result; 21 } 22 23 // sqrt: From Christopher J. Musial, An integer square root, Graphics Gems, 1990, page 387 24 GLM_FUNC_QUALIFIER int sqrt(int x) 25 { 26 if(x <= 1) return x; 27 28 int NextTrial = x >> 1; 29 int CurrentAnswer; 30 31 do 32 { 33 CurrentAnswer = NextTrial; 34 NextTrial = (NextTrial + x / NextTrial) >> 1; 35 } while(NextTrial < CurrentAnswer); 36 37 return CurrentAnswer; 38 } 39 40 // Henry Gordon Dietz: http://aggregate.org/MAGIC/ 41 namespace detail 42 { 43 GLM_FUNC_QUALIFIER unsigned int ones32(unsigned int x) 44 { 45 /* 32-bit recursive reduction using SWAR... 46 but first step is mapping 2-bit values 47 into sum of 2 1-bit values in sneaky way 48 */ 49 x -= ((x >> 1) & 0x55555555); 50 x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); 51 x = (((x >> 4) + x) & 0x0f0f0f0f); 52 x += (x >> 8); 53 x += (x >> 16); 54 return(x & 0x0000003f); 55 } 56 57 template <> 58 struct compute_log2<false> 59 { 60 template <typename T> 61 GLM_FUNC_QUALIFIER T operator() (T const & Value) const 62 { 63 #if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC)) 64 return Value <= static_cast<T>(1) ? T(0) : T(32) - nlz(Value - T(1)); 65 #else 66 return T(32) - nlz(Value - T(1)); 67 #endif 68 } 69 }; 70 }//namespace _detail 71 72 // Henry Gordon Dietz: http://aggregate.org/MAGIC/ 73 /* 74 GLM_FUNC_QUALIFIER unsigned int floor_log2(unsigned int x) 75 { 76 x |= (x >> 1); 77 x |= (x >> 2); 78 x |= (x >> 4); 79 x |= (x >> 8); 80 x |= (x >> 16); 81 82 return _detail::ones32(x) >> 1; 83 } 84 */ 85 // mod 86 GLM_FUNC_QUALIFIER int mod(int x, int y) 87 { 88 return x - y * (x / y); 89 } 90 91 // factorial (!12 max, integer only) 92 template <typename genType> 93 GLM_FUNC_QUALIFIER genType factorial(genType const & x) 94 { 95 genType Temp = x; 96 genType Result; 97 for(Result = 1; Temp > 1; --Temp) 98 Result *= Temp; 99 return Result; 100 } 101 102 template <typename T, precision P> 103 GLM_FUNC_QUALIFIER detail::tvec2<T, P> factorial( 104 detail::tvec2<T, P> const & x) 105 { 106 return detail::tvec2<T, P>( 107 factorial(x.x), 108 factorial(x.y)); 109 } 110 111 template <typename T, precision P> 112 GLM_FUNC_QUALIFIER detail::tvec3<T, P> factorial( 113 detail::tvec3<T, P> const & x) 114 { 115 return detail::tvec3<T, P>( 116 factorial(x.x), 117 factorial(x.y), 118 factorial(x.z)); 119 } 120 121 template <typename T, precision P> 122 GLM_FUNC_QUALIFIER detail::tvec4<T, P> factorial( 123 detail::tvec4<T, P> const & x) 124 { 125 return detail::tvec4<T, P>( 126 factorial(x.x), 127 factorial(x.y), 128 factorial(x.z), 129 factorial(x.w)); 130 } 131 132 GLM_FUNC_QUALIFIER uint pow(uint x, uint y) 133 { 134 uint result = x; 135 for(uint i = 1; i < y; ++i) 136 result *= x; 137 return result; 138 } 139 140 GLM_FUNC_QUALIFIER uint sqrt(uint x) 141 { 142 if(x <= 1) return x; 143 144 uint NextTrial = x >> 1; 145 uint CurrentAnswer; 146 147 do 148 { 149 CurrentAnswer = NextTrial; 150 NextTrial = (NextTrial + x / NextTrial) >> 1; 151 } while(NextTrial < CurrentAnswer); 152 153 return CurrentAnswer; 154 } 155 156 GLM_FUNC_QUALIFIER uint mod(uint x, uint y) 157 { 158 return x - y * (x / y); 159 } 160 161 #if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC)) 162 163 GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x) 164 { 165 return 31u - findMSB(x); 166 } 167 168 #else 169 170 // Hackers Delight: http://www.hackersdelight.org/HDcode/nlz.c.txt 171 GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x) 172 { 173 int y, m, n; 174 175 y = -int(x >> 16); // If left half of x is 0, 176 m = (y >> 16) & 16; // set n = 16. If left half 177 n = 16 - m; // is nonzero, set n = 0 and 178 x = x >> m; // shift x right 16. 179 // Now x is of the form 0000xxxx. 180 y = x - 0x100; // If positions 8-15 are 0, 181 m = (y >> 16) & 8; // add 8 to n and shift x left 8. 182 n = n + m; 183 x = x << m; 184 185 y = x - 0x1000; // If positions 12-15 are 0, 186 m = (y >> 16) & 4; // add 4 to n and shift x left 4. 187 n = n + m; 188 x = x << m; 189 190 y = x - 0x4000; // If positions 14-15 are 0, 191 m = (y >> 16) & 2; // add 2 to n and shift x left 2. 192 n = n + m; 193 x = x << m; 194 195 y = x >> 14; // Set y = 0, 1, 2, or 3. 196 m = y & ~(y >> 1); // Set m = 0, 1, 2, or 2 resp. 197 return unsigned(n + 2 - m); 198 } 199 200 #endif//(GLM_COMPILER) 201 202 }//namespace glm 203