/src/testdir/build/lua-master/source/lmathlib.c
| Line | Count | Source | 
| 1 |  | /* | 
| 2 |  | ** $Id: lmathlib.c $ | 
| 3 |  | ** Standard mathematical library | 
| 4 |  | ** See Copyright Notice in lua.h | 
| 5 |  | */ | 
| 6 |  |  | 
| 7 |  | #define lmathlib_c | 
| 8 |  | #define LUA_LIB | 
| 9 |  |  | 
| 10 |  | #include "lprefix.h" | 
| 11 |  |  | 
| 12 |  |  | 
| 13 |  | #include <float.h> | 
| 14 |  | #include <limits.h> | 
| 15 |  | #include <math.h> | 
| 16 |  | #include <stdlib.h> | 
| 17 |  | #include <time.h> | 
| 18 |  |  | 
| 19 |  | #include "lua.h" | 
| 20 |  |  | 
| 21 |  | #include "lauxlib.h" | 
| 22 |  | #include "lualib.h" | 
| 23 |  | #include "llimits.h" | 
| 24 |  |  | 
| 25 |  |  | 
| 26 |  | #undef PI | 
| 27 | 31.0k | #define PI  (l_mathop(3.141592653589793238462643383279502884)) | 
| 28 |  |  | 
| 29 |  |  | 
| 30 | 2.27k | static int math_abs (lua_State *L) { | 
| 31 | 2.27k |   if (lua_isinteger(L, 1)) { | 
| 32 | 1.13k |     lua_Integer n = lua_tointeger(L, 1); | 
| 33 | 1.13k |     if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n); | 
| 34 | 1.13k |     lua_pushinteger(L, n); | 
| 35 | 1.13k |   } | 
| 36 | 1.14k |   else | 
| 37 | 1.14k |     lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); | 
| 38 | 2.27k |   return 1; | 
| 39 | 2.27k | } | 
| 40 |  |  | 
| 41 |  |  | 
| 42 | 74.1k | static int math_sin (lua_State *L) { | 
| 43 | 74.1k |   lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); | 
| 44 | 74.1k |   return 1; | 
| 45 | 74.1k | } | 
| 46 |  |  | 
| 47 |  |  | 
| 48 | 961 | static int math_cos (lua_State *L) { | 
| 49 | 961 |   lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); | 
| 50 | 961 |   return 1; | 
| 51 | 961 | } | 
| 52 |  |  | 
| 53 |  |  | 
| 54 | 848 | static int math_tan (lua_State *L) { | 
| 55 | 848 |   lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); | 
| 56 | 848 |   return 1; | 
| 57 | 848 | } | 
| 58 |  |  | 
| 59 |  |  | 
| 60 | 62 | static int math_asin (lua_State *L) { | 
| 61 | 62 |   lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); | 
| 62 | 62 |   return 1; | 
| 63 | 62 | } | 
| 64 |  |  | 
| 65 |  |  | 
| 66 | 55 | static int math_acos (lua_State *L) { | 
| 67 | 55 |   lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); | 
| 68 | 55 |   return 1; | 
| 69 | 55 | } | 
| 70 |  |  | 
| 71 |  |  | 
| 72 | 110 | static int math_atan (lua_State *L) { | 
| 73 | 110 |   lua_Number y = luaL_checknumber(L, 1); | 
| 74 | 110 |   lua_Number x = luaL_optnumber(L, 2, 1); | 
| 75 | 110 |   lua_pushnumber(L, l_mathop(atan2)(y, x)); | 
| 76 | 110 |   return 1; | 
| 77 | 110 | } | 
| 78 |  |  | 
| 79 |  |  | 
| 80 | 2.20k | static int math_toint (lua_State *L) { | 
| 81 | 2.20k |   int valid; | 
| 82 | 2.20k |   lua_Integer n = lua_tointegerx(L, 1, &valid); | 
| 83 | 2.20k |   if (l_likely(valid)) | 
| 84 | 76 |     lua_pushinteger(L, n); | 
| 85 | 2.12k |   else { | 
| 86 | 2.12k |     luaL_checkany(L, 1); | 
| 87 | 2.12k |     luaL_pushfail(L);  /* value is not convertible to integer */ | 
| 88 | 2.12k |   } | 
| 89 | 2.20k |   return 1; | 
| 90 | 2.20k | } | 
| 91 |  |  | 
| 92 |  |  | 
| 93 | 2.52M | static void pushnumint (lua_State *L, lua_Number d) { | 
| 94 | 2.52M |   lua_Integer n; | 
| 95 | 2.52M |   if (lua_numbertointeger(d, &n))  /* does 'd' fit in an integer? */ | 
| 96 | 1.15M |     lua_pushinteger(L, n);  /* result is integer */ | 
| 97 | 1.37M |   else | 
| 98 | 1.37M |     lua_pushnumber(L, d);  /* result is float */ | 
| 99 | 2.52M | } | 
| 100 |  |  | 
| 101 |  |  | 
| 102 | 2.52M | static int math_floor (lua_State *L) { | 
| 103 | 2.52M |   if (lua_isinteger(L, 1)) | 
| 104 | 1.13k |     lua_settop(L, 1);  /* integer is its own floor */ | 
| 105 | 2.52M |   else { | 
| 106 | 2.52M |     lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1)); | 
| 107 | 2.52M |     pushnumint(L, d); | 
| 108 | 2.52M |   } | 
| 109 | 2.52M |   return 1; | 
| 110 | 2.52M | } | 
| 111 |  |  | 
| 112 |  |  | 
| 113 | 3.25k | static int math_ceil (lua_State *L) { | 
| 114 | 3.25k |   if (lua_isinteger(L, 1)) | 
| 115 | 1.71k |     lua_settop(L, 1);  /* integer is its own ceiling */ | 
| 116 | 1.53k |   else { | 
| 117 | 1.53k |     lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1)); | 
| 118 | 1.53k |     pushnumint(L, d); | 
| 119 | 1.53k |   } | 
| 120 | 3.25k |   return 1; | 
| 121 | 3.25k | } | 
| 122 |  |  | 
| 123 |  |  | 
| 124 | 56 | static int math_fmod (lua_State *L) { | 
| 125 | 56 |   if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { | 
| 126 | 13 |     lua_Integer d = lua_tointeger(L, 2); | 
| 127 | 13 |     if ((lua_Unsigned)d + 1u <= 1u) {  /* special cases: -1 or 0 */ | 
| 128 | 1 |       luaL_argcheck(L, d != 0, 2, "zero"); | 
| 129 | 1 |       lua_pushinteger(L, 0);  /* avoid overflow with 0x80000... / -1 */ | 
| 130 | 1 |     } | 
| 131 | 12 |     else | 
| 132 | 12 |       lua_pushinteger(L, lua_tointeger(L, 1) % d); | 
| 133 | 13 |   } | 
| 134 | 43 |   else | 
| 135 | 43 |     lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), | 
| 136 | 43 |                                      luaL_checknumber(L, 2))); | 
| 137 | 56 |   return 1; | 
| 138 | 56 | } | 
| 139 |  |  | 
| 140 |  |  | 
| 141 |  | /* | 
| 142 |  | ** next function does not use 'modf', avoiding problems with 'double*' | 
| 143 |  | ** (which is not compatible with 'float*') when lua_Number is not | 
| 144 |  | ** 'double'. | 
| 145 |  | */ | 
| 146 | 4.21k | static int math_modf (lua_State *L) { | 
| 147 | 4.21k |   if (lua_isinteger(L ,1)) { | 
| 148 | 4 |     lua_settop(L, 1);  /* number is its own integer part */ | 
| 149 | 4 |     lua_pushnumber(L, 0);  /* no fractional part */ | 
| 150 | 4 |   } | 
| 151 | 4.20k |   else { | 
| 152 | 4.20k |     lua_Number n = luaL_checknumber(L, 1); | 
| 153 |  |     /* integer part (rounds toward zero) */ | 
| 154 | 4.20k |     lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n); | 
| 155 | 4.20k |     pushnumint(L, ip); | 
| 156 |  |     /* fractional part (test needed for inf/-inf) */ | 
| 157 | 4.20k |     lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); | 
| 158 | 4.20k |   } | 
| 159 | 4.21k |   return 2; | 
| 160 | 4.21k | } | 
| 161 |  |  | 
| 162 |  |  | 
| 163 | 1.58k | static int math_sqrt (lua_State *L) { | 
| 164 | 1.58k |   lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); | 
| 165 | 1.58k |   return 1; | 
| 166 | 1.58k | } | 
| 167 |  |  | 
| 168 |  |  | 
| 169 | 23 | static int math_ult (lua_State *L) { | 
| 170 | 23 |   lua_Integer a = luaL_checkinteger(L, 1); | 
| 171 | 23 |   lua_Integer b = luaL_checkinteger(L, 2); | 
| 172 | 23 |   lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b); | 
| 173 | 23 |   return 1; | 
| 174 | 23 | } | 
| 175 |  |  | 
| 176 |  |  | 
| 177 | 514 | static int math_log (lua_State *L) { | 
| 178 | 514 |   lua_Number x = luaL_checknumber(L, 1); | 
| 179 | 514 |   lua_Number res; | 
| 180 | 514 |   if (lua_isnoneornil(L, 2)) | 
| 181 | 510 |     res = l_mathop(log)(x); | 
| 182 | 4 |   else { | 
| 183 | 4 |     lua_Number base = luaL_checknumber(L, 2); | 
| 184 | 4 | #if !defined(LUA_USE_C89) | 
| 185 | 4 |     if (base == l_mathop(2.0)) | 
| 186 | 0 |       res = l_mathop(log2)(x); | 
| 187 | 4 |     else | 
| 188 | 4 | #endif | 
| 189 | 4 |     if (base == l_mathop(10.0)) | 
| 190 | 0 |       res = l_mathop(log10)(x); | 
| 191 | 4 |     else | 
| 192 | 4 |       res = l_mathop(log)(x)/l_mathop(log)(base); | 
| 193 | 4 |   } | 
| 194 | 514 |   lua_pushnumber(L, res); | 
| 195 | 514 |   return 1; | 
| 196 | 514 | } | 
| 197 |  |  | 
| 198 |  |  | 
| 199 | 1.65k | static int math_exp (lua_State *L) { | 
| 200 | 1.65k |   lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); | 
| 201 | 1.65k |   return 1; | 
| 202 | 1.65k | } | 
| 203 |  |  | 
| 204 |  |  | 
| 205 | 1.26k | static int math_deg (lua_State *L) { | 
| 206 | 1.26k |   lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI)); | 
| 207 | 1.26k |   return 1; | 
| 208 | 1.26k | } | 
| 209 |  |  | 
| 210 |  |  | 
| 211 | 78 | static int math_rad (lua_State *L) { | 
| 212 | 78 |   lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0))); | 
| 213 | 78 |   return 1; | 
| 214 | 78 | } | 
| 215 |  |  | 
| 216 |  |  | 
| 217 | 0 | static int math_frexp (lua_State *L) { | 
| 218 | 0 |   lua_Number x = luaL_checknumber(L, 1); | 
| 219 | 0 |   int ep; | 
| 220 | 0 |   lua_pushnumber(L, l_mathop(frexp)(x, &ep)); | 
| 221 | 0 |   lua_pushinteger(L, ep); | 
| 222 | 0 |   return 2; | 
| 223 | 0 | } | 
| 224 |  |  | 
| 225 |  |  | 
| 226 | 0 | static int math_ldexp (lua_State *L) { | 
| 227 | 0 |   lua_Number x = luaL_checknumber(L, 1); | 
| 228 | 0 |   int ep = (int)luaL_checkinteger(L, 2); | 
| 229 | 0 |   lua_pushnumber(L, l_mathop(ldexp)(x, ep)); | 
| 230 | 0 |   return 1; | 
| 231 | 0 | } | 
| 232 |  |  | 
| 233 |  |  | 
| 234 | 1.76k | static int math_min (lua_State *L) { | 
| 235 | 1.76k |   int n = lua_gettop(L);  /* number of arguments */ | 
| 236 | 1.76k |   int imin = 1;  /* index of current minimum value */ | 
| 237 | 1.76k |   int i; | 
| 238 | 1.76k |   luaL_argcheck(L, n >= 1, 1, "value expected"); | 
| 239 | 2.45k |   for (i = 2; i <= n; i++) { | 
| 240 | 691 |     if (lua_compare(L, i, imin, LUA_OPLT)) | 
| 241 | 256 |       imin = i; | 
| 242 | 691 |   } | 
| 243 | 1.76k |   lua_pushvalue(L, imin); | 
| 244 | 1.76k |   return 1; | 
| 245 | 1.76k | } | 
| 246 |  |  | 
| 247 |  |  | 
| 248 | 2.02k | static int math_max (lua_State *L) { | 
| 249 | 2.02k |   int n = lua_gettop(L);  /* number of arguments */ | 
| 250 | 2.02k |   int imax = 1;  /* index of current maximum value */ | 
| 251 | 2.02k |   int i; | 
| 252 | 2.02k |   luaL_argcheck(L, n >= 1, 1, "value expected"); | 
| 253 | 3.11k |   for (i = 2; i <= n; i++) { | 
| 254 | 1.08k |     if (lua_compare(L, imax, i, LUA_OPLT)) | 
| 255 | 863 |       imax = i; | 
| 256 | 1.08k |   } | 
| 257 | 2.02k |   lua_pushvalue(L, imax); | 
| 258 | 2.02k |   return 1; | 
| 259 | 2.02k | } | 
| 260 |  |  | 
| 261 |  |  | 
| 262 | 191 | static int math_type (lua_State *L) { | 
| 263 | 191 |   if (lua_type(L, 1) == LUA_TNUMBER) | 
| 264 | 0 |     lua_pushstring(L, (lua_isinteger(L, 1)) ? "integer" : "float"); | 
| 265 | 191 |   else { | 
| 266 | 191 |     luaL_checkany(L, 1); | 
| 267 | 191 |     luaL_pushfail(L); | 
| 268 | 191 |   } | 
| 269 | 191 |   return 1; | 
| 270 | 191 | } | 
| 271 |  |  | 
| 272 |  |  | 
| 273 |  |  | 
| 274 |  | /* | 
| 275 |  | ** {================================================================== | 
| 276 |  | ** Pseudo-Random Number Generator based on 'xoshiro256**'. | 
| 277 |  | ** =================================================================== | 
| 278 |  | */ | 
| 279 |  |  | 
| 280 |  | /* | 
| 281 |  | ** This code uses lots of shifts. ISO C does not allow shifts greater | 
| 282 |  | ** than or equal to the width of the type being shifted, so some shifts | 
| 283 |  | ** are written in convoluted ways to match that restriction. For | 
| 284 |  | ** preprocessor tests, it assumes a width of 32 bits, so the maximum | 
| 285 |  | ** shift there is 31 bits. | 
| 286 |  | */ | 
| 287 |  |  | 
| 288 |  |  | 
| 289 |  | /* number of binary digits in the mantissa of a float */ | 
| 290 | 0 | #define FIGS  l_floatatt(MANT_DIG) | 
| 291 |  |  | 
| 292 |  | #if FIGS > 64 | 
| 293 |  | /* there are only 64 random bits; use them all */ | 
| 294 |  | #undef FIGS | 
| 295 |  | #define FIGS  64 | 
| 296 |  | #endif | 
| 297 |  |  | 
| 298 |  |  | 
| 299 |  | /* | 
| 300 |  | ** LUA_RAND32 forces the use of 32-bit integers in the implementation | 
| 301 |  | ** of the PRN generator (mainly for testing). | 
| 302 |  | */ | 
| 303 |  | #if !defined(LUA_RAND32) && !defined(Rand64) | 
| 304 |  |  | 
| 305 |  | /* try to find an integer type with at least 64 bits */ | 
| 306 |  |  | 
| 307 |  | #if ((ULONG_MAX >> 31) >> 31) >= 3 | 
| 308 |  |  | 
| 309 |  | /* 'long' has at least 64 bits */ | 
| 310 | 2.62M | #define Rand64    unsigned long | 
| 311 | 0 | #define SRand64   long | 
| 312 |  |  | 
| 313 |  | #elif !defined(LUA_USE_C89) && defined(LLONG_MAX) | 
| 314 |  |  | 
| 315 |  | /* there is a 'long long' type (which must have at least 64 bits) */ | 
| 316 |  | #define Rand64    unsigned long long | 
| 317 |  | #define SRand64   long long | 
| 318 |  |  | 
| 319 |  | #elif ((LUA_MAXUNSIGNED >> 31) >> 31) >= 3 | 
| 320 |  |  | 
| 321 |  | /* 'lua_Unsigned' has at least 64 bits */ | 
| 322 |  | #define Rand64    lua_Unsigned | 
| 323 |  | #define SRand64   lua_Integer | 
| 324 |  |  | 
| 325 |  | #endif | 
| 326 |  |  | 
| 327 |  | #endif | 
| 328 |  |  | 
| 329 |  |  | 
| 330 |  | #if defined(Rand64)  /* { */ | 
| 331 |  |  | 
| 332 |  | /* | 
| 333 |  | ** Standard implementation, using 64-bit integers. | 
| 334 |  | ** If 'Rand64' has more than 64 bits, the extra bits do not interfere | 
| 335 |  | ** with the 64 initial bits, except in a right shift. Moreover, the | 
| 336 |  | ** final result has to discard the extra bits. | 
| 337 |  | */ | 
| 338 |  |  | 
| 339 |  | /* avoid using extra bits when needed */ | 
| 340 | 1.08M | #define trim64(x) ((x) & 0xffffffffffffffffu) | 
| 341 |  |  | 
| 342 |  |  | 
| 343 |  | /* rotate left 'x' by 'n' bits */ | 
| 344 | 1.03M | static Rand64 rotl (Rand64 x, int n) { | 
| 345 | 1.03M |   return (x << n) | (trim64(x) >> (64 - n)); | 
| 346 | 1.03M | } | 
| 347 |  |  | 
| 348 | 518k | static Rand64 nextrand (Rand64 *state) { | 
| 349 | 518k |   Rand64 state0 = state[0]; | 
| 350 | 518k |   Rand64 state1 = state[1]; | 
| 351 | 518k |   Rand64 state2 = state[2] ^ state0; | 
| 352 | 518k |   Rand64 state3 = state[3] ^ state1; | 
| 353 | 518k |   Rand64 res = rotl(state1 * 5, 7) * 9; | 
| 354 | 518k |   state[0] = state0 ^ state3; | 
| 355 | 518k |   state[1] = state1 ^ state2; | 
| 356 | 518k |   state[2] = state2 ^ (state1 << 17); | 
| 357 | 518k |   state[3] = rotl(state3, 45); | 
| 358 | 518k |   return res; | 
| 359 | 518k | } | 
| 360 |  |  | 
| 361 |  |  | 
| 362 |  | /* | 
| 363 |  | ** Convert bits from a random integer into a float in the | 
| 364 |  | ** interval [0,1), getting the higher FIG bits from the | 
| 365 |  | ** random unsigned integer and converting that to a float. | 
| 366 |  | ** Some old Microsoft compilers cannot cast an unsigned long | 
| 367 |  | ** to a floating-point number, so we use a signed long as an | 
| 368 |  | ** intermediary. When lua_Number is float or double, the shift ensures | 
| 369 |  | ** that 'sx' is non negative; in that case, a good compiler will remove | 
| 370 |  | ** the correction. | 
| 371 |  | */ | 
| 372 |  |  | 
| 373 |  | /* must throw out the extra (64 - FIGS) bits */ | 
| 374 | 0 | #define shift64_FIG (64 - FIGS) | 
| 375 |  |  | 
| 376 |  | /* 2^(-FIGS) == 2^-1 / 2^(FIGS-1) */ | 
| 377 | 0 | #define scaleFIG  (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1))) | 
| 378 |  |  | 
| 379 | 0 | static lua_Number I2d (Rand64 x) { | 
| 380 | 0 |   SRand64 sx = (SRand64)(trim64(x) >> shift64_FIG); | 
| 381 | 0 |   lua_Number res = (lua_Number)(sx) * scaleFIG; | 
| 382 | 0 |   if (sx < 0) | 
| 383 | 0 |     res += l_mathop(1.0);  /* correct the two's complement if negative */ | 
| 384 | 0 |   lua_assert(0 <= res && res < 1); | 
| 385 | 0 |   return res; | 
| 386 | 0 | } | 
| 387 |  |  | 
| 388 |  | /* convert a 'Rand64' to a 'lua_Unsigned' */ | 
| 389 | 42.5k | #define I2UInt(x) ((lua_Unsigned)trim64(x)) | 
| 390 |  |  | 
| 391 |  | /* convert a 'lua_Unsigned' to a 'Rand64' */ | 
| 392 | 118k | #define Int2I(x)  ((Rand64)(x)) | 
| 393 |  |  | 
| 394 |  |  | 
| 395 |  | #else /* no 'Rand64'   }{ */ | 
| 396 |  |  | 
| 397 |  | /* | 
| 398 |  | ** Use two 32-bit integers to represent a 64-bit quantity. | 
| 399 |  | */ | 
| 400 |  | typedef struct Rand64 { | 
| 401 |  |   l_uint32 h;  /* higher half */ | 
| 402 |  |   l_uint32 l;  /* lower half */ | 
| 403 |  | } Rand64; | 
| 404 |  |  | 
| 405 |  |  | 
| 406 |  | /* | 
| 407 |  | ** If 'l_uint32' has more than 32 bits, the extra bits do not interfere | 
| 408 |  | ** with the 32 initial bits, except in a right shift and comparisons. | 
| 409 |  | ** Moreover, the final result has to discard the extra bits. | 
| 410 |  | */ | 
| 411 |  |  | 
| 412 |  | /* avoid using extra bits when needed */ | 
| 413 |  | #define trim32(x) ((x) & 0xffffffffu) | 
| 414 |  |  | 
| 415 |  |  | 
| 416 |  | /* | 
| 417 |  | ** basic operations on 'Rand64' values | 
| 418 |  | */ | 
| 419 |  |  | 
| 420 |  | /* build a new Rand64 value */ | 
| 421 |  | static Rand64 packI (l_uint32 h, l_uint32 l) { | 
| 422 |  |   Rand64 result; | 
| 423 |  |   result.h = h; | 
| 424 |  |   result.l = l; | 
| 425 |  |   return result; | 
| 426 |  | } | 
| 427 |  |  | 
| 428 |  | /* return i << n */ | 
| 429 |  | static Rand64 Ishl (Rand64 i, int n) { | 
| 430 |  |   lua_assert(n > 0 && n < 32); | 
| 431 |  |   return packI((i.h << n) | (trim32(i.l) >> (32 - n)), i.l << n); | 
| 432 |  | } | 
| 433 |  |  | 
| 434 |  | /* i1 ^= i2 */ | 
| 435 |  | static void Ixor (Rand64 *i1, Rand64 i2) { | 
| 436 |  |   i1->h ^= i2.h; | 
| 437 |  |   i1->l ^= i2.l; | 
| 438 |  | } | 
| 439 |  |  | 
| 440 |  | /* return i1 + i2 */ | 
| 441 |  | static Rand64 Iadd (Rand64 i1, Rand64 i2) { | 
| 442 |  |   Rand64 result = packI(i1.h + i2.h, i1.l + i2.l); | 
| 443 |  |   if (trim32(result.l) < trim32(i1.l))  /* carry? */ | 
| 444 |  |     result.h++; | 
| 445 |  |   return result; | 
| 446 |  | } | 
| 447 |  |  | 
| 448 |  | /* return i * 5 */ | 
| 449 |  | static Rand64 times5 (Rand64 i) { | 
| 450 |  |   return Iadd(Ishl(i, 2), i);  /* i * 5 == (i << 2) + i */ | 
| 451 |  | } | 
| 452 |  |  | 
| 453 |  | /* return i * 9 */ | 
| 454 |  | static Rand64 times9 (Rand64 i) { | 
| 455 |  |   return Iadd(Ishl(i, 3), i);  /* i * 9 == (i << 3) + i */ | 
| 456 |  | } | 
| 457 |  |  | 
| 458 |  | /* return 'i' rotated left 'n' bits */ | 
| 459 |  | static Rand64 rotl (Rand64 i, int n) { | 
| 460 |  |   lua_assert(n > 0 && n < 32); | 
| 461 |  |   return packI((i.h << n) | (trim32(i.l) >> (32 - n)), | 
| 462 |  |                (trim32(i.h) >> (32 - n)) | (i.l << n)); | 
| 463 |  | } | 
| 464 |  |  | 
| 465 |  | /* for offsets larger than 32, rotate right by 64 - offset */ | 
| 466 |  | static Rand64 rotl1 (Rand64 i, int n) { | 
| 467 |  |   lua_assert(n > 32 && n < 64); | 
| 468 |  |   n = 64 - n; | 
| 469 |  |   return packI((trim32(i.h) >> n) | (i.l << (32 - n)), | 
| 470 |  |                (i.h << (32 - n)) | (trim32(i.l) >> n)); | 
| 471 |  | } | 
| 472 |  |  | 
| 473 |  | /* | 
| 474 |  | ** implementation of 'xoshiro256**' algorithm on 'Rand64' values | 
| 475 |  | */ | 
| 476 |  | static Rand64 nextrand (Rand64 *state) { | 
| 477 |  |   Rand64 res = times9(rotl(times5(state[1]), 7)); | 
| 478 |  |   Rand64 t = Ishl(state[1], 17); | 
| 479 |  |   Ixor(&state[2], state[0]); | 
| 480 |  |   Ixor(&state[3], state[1]); | 
| 481 |  |   Ixor(&state[1], state[2]); | 
| 482 |  |   Ixor(&state[0], state[3]); | 
| 483 |  |   Ixor(&state[2], t); | 
| 484 |  |   state[3] = rotl1(state[3], 45); | 
| 485 |  |   return res; | 
| 486 |  | } | 
| 487 |  |  | 
| 488 |  |  | 
| 489 |  | /* | 
| 490 |  | ** Converts a 'Rand64' into a float. | 
| 491 |  | */ | 
| 492 |  |  | 
| 493 |  | /* an unsigned 1 with proper type */ | 
| 494 |  | #define UONE    ((l_uint32)1) | 
| 495 |  |  | 
| 496 |  |  | 
| 497 |  | #if FIGS <= 32 | 
| 498 |  |  | 
| 499 |  | /* 2^(-FIGS) */ | 
| 500 |  | #define scaleFIG       (l_mathop(0.5) / (UONE << (FIGS - 1))) | 
| 501 |  |  | 
| 502 |  | /* | 
| 503 |  | ** get up to 32 bits from higher half, shifting right to | 
| 504 |  | ** throw out the extra bits. | 
| 505 |  | */ | 
| 506 |  | static lua_Number I2d (Rand64 x) { | 
| 507 |  |   lua_Number h = (lua_Number)(trim32(x.h) >> (32 - FIGS)); | 
| 508 |  |   return h * scaleFIG; | 
| 509 |  | } | 
| 510 |  |  | 
| 511 |  | #else /* 32 < FIGS <= 64 */ | 
| 512 |  |  | 
| 513 |  | /* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */ | 
| 514 |  | #define scaleFIG  \ | 
| 515 |  |     (l_mathop(1.0) / (UONE << 30) / l_mathop(8.0) / (UONE << (FIGS - 33))) | 
| 516 |  |  | 
| 517 |  | /* | 
| 518 |  | ** use FIGS - 32 bits from lower half, throwing out the other | 
| 519 |  | ** (32 - (FIGS - 32)) = (64 - FIGS) bits | 
| 520 |  | */ | 
| 521 |  | #define shiftLOW  (64 - FIGS) | 
| 522 |  |  | 
| 523 |  | /* | 
| 524 |  | ** higher 32 bits go after those (FIGS - 32) bits: shiftHI = 2^(FIGS - 32) | 
| 525 |  | */ | 
| 526 |  | #define shiftHI   ((lua_Number)(UONE << (FIGS - 33)) * l_mathop(2.0)) | 
| 527 |  |  | 
| 528 |  |  | 
| 529 |  | static lua_Number I2d (Rand64 x) { | 
| 530 |  |   lua_Number h = (lua_Number)trim32(x.h) * shiftHI; | 
| 531 |  |   lua_Number l = (lua_Number)(trim32(x.l) >> shiftLOW); | 
| 532 |  |   return (h + l) * scaleFIG; | 
| 533 |  | } | 
| 534 |  |  | 
| 535 |  | #endif | 
| 536 |  |  | 
| 537 |  |  | 
| 538 |  | /* convert a 'Rand64' to a 'lua_Unsigned' */ | 
| 539 |  | static lua_Unsigned I2UInt (Rand64 x) { | 
| 540 |  |   return (((lua_Unsigned)trim32(x.h) << 31) << 1) | (lua_Unsigned)trim32(x.l); | 
| 541 |  | } | 
| 542 |  |  | 
| 543 |  | /* convert a 'lua_Unsigned' to a 'Rand64' */ | 
| 544 |  | static Rand64 Int2I (lua_Unsigned n) { | 
| 545 |  |   return packI((l_uint32)((n >> 31) >> 1), (l_uint32)n); | 
| 546 |  | } | 
| 547 |  |  | 
| 548 |  | #endif  /* } */ | 
| 549 |  |  | 
| 550 |  |  | 
| 551 |  | /* | 
| 552 |  | ** A state uses four 'Rand64' values. | 
| 553 |  | */ | 
| 554 |  | typedef struct { | 
| 555 |  |   Rand64 s[4]; | 
| 556 |  | } RanState; | 
| 557 |  |  | 
| 558 |  |  | 
| 559 |  | /* | 
| 560 |  | ** Project the random integer 'ran' into the interval [0, n]. | 
| 561 |  | ** Because 'ran' has 2^B possible values, the projection can only be | 
| 562 |  | ** uniform when the size of the interval is a power of 2 (exact | 
| 563 |  | ** division). So, to get a uniform projection into [0, n], we | 
| 564 |  | ** first compute 'lim', the smallest Mersenne number not smaller than | 
| 565 |  | ** 'n'. We then project 'ran' into the interval [0, lim].  If the result | 
| 566 |  | ** is inside [0, n], we are done. Otherwise, we try with another 'ran', | 
| 567 |  | ** until we have a result inside the interval. | 
| 568 |  | */ | 
| 569 |  | static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, | 
| 570 | 30.0k |                              RanState *state) { | 
| 571 | 30.0k |   lua_Unsigned lim = n;  /* to compute the Mersenne number */ | 
| 572 | 30.0k |   int sh;  /* how much to spread bits to the right in 'lim' */ | 
| 573 |  |   /* spread '1' bits in 'lim' until it becomes a Mersenne number */ | 
| 574 | 85.4k |   for (sh = 1; (lim & (lim + 1)) != 0; sh *= 2) | 
| 575 | 55.3k |     lim |= (lim >> sh);  /* spread '1's to the right */ | 
| 576 | 42.5k |   while ((ran &= lim) > n)  /* project 'ran' into [0..lim] and test */ | 
| 577 | 12.4k |     ran = I2UInt(nextrand(state->s));  /* not inside [0..n]? try again */ | 
| 578 | 30.0k |   return ran; | 
| 579 | 30.0k | } | 
| 580 |  |  | 
| 581 |  |  | 
| 582 | 30.8k | static int math_random (lua_State *L) { | 
| 583 | 30.8k |   lua_Integer low, up; | 
| 584 | 30.8k |   lua_Unsigned p; | 
| 585 | 30.8k |   RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); | 
| 586 | 30.8k |   Rand64 rv = nextrand(state->s);  /* next pseudo-random value */ | 
| 587 | 30.8k |   switch (lua_gettop(L)) {  /* check number of arguments */ | 
| 588 | 0 |     case 0: {  /* no arguments */ | 
| 589 | 0 |       lua_pushnumber(L, I2d(rv));  /* float between 0 and 1 */ | 
| 590 | 0 |       return 1; | 
| 591 | 0 |     } | 
| 592 | 9.11k |     case 1: {  /* only upper limit */ | 
| 593 | 9.11k |       low = 1; | 
| 594 | 9.11k |       up = luaL_checkinteger(L, 1); | 
| 595 | 9.11k |       if (up == 0) {  /* single 0 as argument? */ | 
| 596 | 727 |         lua_pushinteger(L, l_castU2S(I2UInt(rv)));  /* full random integer */ | 
| 597 | 727 |         return 1; | 
| 598 | 727 |       } | 
| 599 | 8.38k |       break; | 
| 600 | 9.11k |     } | 
| 601 | 21.7k |     case 2: {  /* lower and upper limits */ | 
| 602 | 21.7k |       low = luaL_checkinteger(L, 1); | 
| 603 | 21.7k |       up = luaL_checkinteger(L, 2); | 
| 604 | 21.7k |       break; | 
| 605 | 9.11k |     } | 
| 606 | 0 |     default: return luaL_error(L, "wrong number of arguments"); | 
| 607 | 30.8k |   } | 
| 608 |  |   /* random integer in the interval [low, up] */ | 
| 609 | 30.0k |   luaL_argcheck(L, low <= up, 1, "interval is empty"); | 
| 610 |  |   /* project random integer into the interval [0, up - low] */ | 
| 611 | 30.0k |   p = project(I2UInt(rv), l_castS2U(up) - l_castS2U(low), state); | 
| 612 | 30.0k |   lua_pushinteger(L, l_castU2S(p + l_castS2U(low))); | 
| 613 | 30.0k |   return 1; | 
| 614 | 30.8k | } | 
| 615 |  |  | 
| 616 |  |  | 
| 617 |  | static void setseed (lua_State *L, Rand64 *state, | 
| 618 | 29.7k |                      lua_Unsigned n1, lua_Unsigned n2) { | 
| 619 | 29.7k |   int i; | 
| 620 | 29.7k |   state[0] = Int2I(n1); | 
| 621 | 29.7k |   state[1] = Int2I(0xff);  /* avoid a zero state */ | 
| 622 | 29.7k |   state[2] = Int2I(n2); | 
| 623 | 29.7k |   state[3] = Int2I(0); | 
| 624 | 505k |   for (i = 0; i < 16; i++) | 
| 625 | 475k |     nextrand(state);  /* discard initial values to "spread" seed */ | 
| 626 | 29.7k |   lua_pushinteger(L, l_castU2S(n1)); | 
| 627 | 29.7k |   lua_pushinteger(L, l_castU2S(n2)); | 
| 628 | 29.7k | } | 
| 629 |  |  | 
| 630 |  |  | 
| 631 | 48 | static int math_randomseed (lua_State *L) { | 
| 632 | 48 |   RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); | 
| 633 | 48 |   lua_Unsigned n1, n2; | 
| 634 | 48 |   if (lua_isnone(L, 1)) { | 
| 635 | 1 |     n1 = luaL_makeseed(L);  /* "random" seed */ | 
| 636 | 1 |     n2 = I2UInt(nextrand(state->s));  /* in case seed is not that random... */ | 
| 637 | 1 |   } | 
| 638 | 47 |   else { | 
| 639 | 47 |     n1 = l_castS2U(luaL_checkinteger(L, 1)); | 
| 640 | 47 |     n2 = l_castS2U(luaL_optinteger(L, 2, 0)); | 
| 641 | 47 |   } | 
| 642 | 48 |   setseed(L, state->s, n1, n2); | 
| 643 | 48 |   return 2;  /* return seeds */ | 
| 644 | 48 | } | 
| 645 |  |  | 
| 646 |  |  | 
| 647 |  | static const luaL_Reg randfuncs[] = { | 
| 648 |  |   {"random", math_random}, | 
| 649 |  |   {"randomseed", math_randomseed}, | 
| 650 |  |   {NULL, NULL} | 
| 651 |  | }; | 
| 652 |  |  | 
| 653 |  |  | 
| 654 |  | /* | 
| 655 |  | ** Register the random functions and initialize their state. | 
| 656 |  | */ | 
| 657 | 29.6k | static void setrandfunc (lua_State *L) { | 
| 658 | 29.6k |   RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0); | 
| 659 | 29.6k |   setseed(L, state->s, luaL_makeseed(L), 0);  /* initialize with random seed */ | 
| 660 | 29.6k |   lua_pop(L, 2);  /* remove pushed seeds */ | 
| 661 | 29.6k |   luaL_setfuncs(L, randfuncs, 1); | 
| 662 | 29.6k | } | 
| 663 |  |  | 
| 664 |  | /* }================================================================== */ | 
| 665 |  |  | 
| 666 |  |  | 
| 667 |  | /* | 
| 668 |  | ** {================================================================== | 
| 669 |  | ** Deprecated functions (for compatibility only) | 
| 670 |  | ** =================================================================== | 
| 671 |  | */ | 
| 672 |  | #if defined(LUA_COMPAT_MATHLIB) | 
| 673 |  |  | 
| 674 |  | static int math_cosh (lua_State *L) { | 
| 675 |  |   lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); | 
| 676 |  |   return 1; | 
| 677 |  | } | 
| 678 |  |  | 
| 679 |  | static int math_sinh (lua_State *L) { | 
| 680 |  |   lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); | 
| 681 |  |   return 1; | 
| 682 |  | } | 
| 683 |  |  | 
| 684 |  | static int math_tanh (lua_State *L) { | 
| 685 |  |   lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); | 
| 686 |  |   return 1; | 
| 687 |  | } | 
| 688 |  |  | 
| 689 |  | static int math_pow (lua_State *L) { | 
| 690 |  |   lua_Number x = luaL_checknumber(L, 1); | 
| 691 |  |   lua_Number y = luaL_checknumber(L, 2); | 
| 692 |  |   lua_pushnumber(L, l_mathop(pow)(x, y)); | 
| 693 |  |   return 1; | 
| 694 |  | } | 
| 695 |  |  | 
| 696 |  | static int math_log10 (lua_State *L) { | 
| 697 |  |   lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); | 
| 698 |  |   return 1; | 
| 699 |  | } | 
| 700 |  |  | 
| 701 |  | #endif | 
| 702 |  | /* }================================================================== */ | 
| 703 |  |  | 
| 704 |  |  | 
| 705 |  |  | 
| 706 |  | static const luaL_Reg mathlib[] = { | 
| 707 |  |   {"abs",   math_abs}, | 
| 708 |  |   {"acos",  math_acos}, | 
| 709 |  |   {"asin",  math_asin}, | 
| 710 |  |   {"atan",  math_atan}, | 
| 711 |  |   {"ceil",  math_ceil}, | 
| 712 |  |   {"cos",   math_cos}, | 
| 713 |  |   {"deg",   math_deg}, | 
| 714 |  |   {"exp",   math_exp}, | 
| 715 |  |   {"tointeger", math_toint}, | 
| 716 |  |   {"floor", math_floor}, | 
| 717 |  |   {"fmod",   math_fmod}, | 
| 718 |  |   {"frexp", math_frexp}, | 
| 719 |  |   {"ult",   math_ult}, | 
| 720 |  |   {"ldexp", math_ldexp}, | 
| 721 |  |   {"log",   math_log}, | 
| 722 |  |   {"max",   math_max}, | 
| 723 |  |   {"min",   math_min}, | 
| 724 |  |   {"modf",   math_modf}, | 
| 725 |  |   {"rad",   math_rad}, | 
| 726 |  |   {"sin",   math_sin}, | 
| 727 |  |   {"sqrt",  math_sqrt}, | 
| 728 |  |   {"tan",   math_tan}, | 
| 729 |  |   {"type", math_type}, | 
| 730 |  | #if defined(LUA_COMPAT_MATHLIB) | 
| 731 |  |   {"atan2", math_atan}, | 
| 732 |  |   {"cosh",   math_cosh}, | 
| 733 |  |   {"sinh",   math_sinh}, | 
| 734 |  |   {"tanh",   math_tanh}, | 
| 735 |  |   {"pow",   math_pow}, | 
| 736 |  |   {"log10", math_log10}, | 
| 737 |  | #endif | 
| 738 |  |   /* placeholders */ | 
| 739 |  |   {"random", NULL}, | 
| 740 |  |   {"randomseed", NULL}, | 
| 741 |  |   {"pi", NULL}, | 
| 742 |  |   {"huge", NULL}, | 
| 743 |  |   {"maxinteger", NULL}, | 
| 744 |  |   {"mininteger", NULL}, | 
| 745 |  |   {NULL, NULL} | 
| 746 |  | }; | 
| 747 |  |  | 
| 748 |  |  | 
| 749 |  | /* | 
| 750 |  | ** Open math library | 
| 751 |  | */ | 
| 752 | 29.6k | LUAMOD_API int luaopen_math (lua_State *L) { | 
| 753 | 29.6k |   luaL_newlib(L, mathlib); | 
| 754 | 29.6k |   lua_pushnumber(L, PI); | 
| 755 | 29.6k |   lua_setfield(L, -2, "pi"); | 
| 756 | 29.6k |   lua_pushnumber(L, (lua_Number)HUGE_VAL); | 
| 757 | 29.6k |   lua_setfield(L, -2, "huge"); | 
| 758 | 29.6k |   lua_pushinteger(L, LUA_MAXINTEGER); | 
| 759 | 29.6k |   lua_setfield(L, -2, "maxinteger"); | 
| 760 |  |   lua_pushinteger(L, LUA_MININTEGER); | 
| 761 | 29.6k |   lua_setfield(L, -2, "mininteger"); | 
| 762 | 29.6k |   setrandfunc(L); | 
| 763 | 29.6k |   return 1; | 
| 764 | 29.6k | } | 
| 765 |  |  |