1 /* $NetBSD: lmathlib.c,v 1.9 2018/08/04 17:30:01 alnsn Exp $ */ 2 3 /* 4 ** Id: lmathlib.c,v 1.119.1.1 2017/04/19 17:20:42 roberto Exp 5 ** Standard mathematical library 6 ** See Copyright Notice in lua.h 7 */ 8 9 #define lmathlib_c 10 #define LUA_LIB 11 12 #include "lprefix.h" 13 14 15 #include <stdlib.h> 16 #include <math.h> 17 18 #include "lua.h" 19 20 #include "lauxlib.h" 21 #include "lualib.h" 22 23 24 #undef PI 25 #define PI (l_mathop(3.141592653589793238462643383279502884)) 26 27 28 #if !defined(l_rand) /* { */ 29 #if defined(LUA_USE_POSIX) 30 #define l_rand() random() 31 #define l_srand(x) srandom(x) 32 #define L_RANDMAX 2147483647 /* (2^31 - 1), following POSIX */ 33 #else 34 #define l_rand() rand() 35 #define l_srand(x) srand(x) 36 #define L_RANDMAX RAND_MAX 37 #endif 38 #endif /* } */ 39 40 41 static int math_abs (lua_State *L) { 42 if (lua_isinteger(L, 1)) { 43 lua_Integer n = lua_tointeger(L, 1); 44 if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n); 45 lua_pushinteger(L, n); 46 } 47 else 48 lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); 49 return 1; 50 } 51 52 static int math_sin (lua_State *L) { 53 lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); 54 return 1; 55 } 56 57 static int math_cos (lua_State *L) { 58 lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); 59 return 1; 60 } 61 62 static int math_tan (lua_State *L) { 63 lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); 64 return 1; 65 } 66 67 static int math_asin (lua_State *L) { 68 lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); 69 return 1; 70 } 71 72 static int math_acos (lua_State *L) { 73 lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); 74 return 1; 75 } 76 77 static int math_atan (lua_State *L) { 78 lua_Number y = luaL_checknumber(L, 1); 79 lua_Number x = luaL_optnumber(L, 2, 1); 80 lua_pushnumber(L, l_mathop(atan2)(y, x)); 81 return 1; 82 } 83 84 85 static int math_toint (lua_State *L) { 86 int valid; 87 lua_Integer n = lua_tointegerx(L, 1, &valid); 88 if (valid) 89 lua_pushinteger(L, n); 90 else { 91 luaL_checkany(L, 1); 92 lua_pushnil(L); /* value is not convertible to integer */ 93 } 94 return 1; 95 } 96 97 98 static void pushnumint (lua_State *L, lua_Number d) { 99 lua_Integer n; 100 if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */ 101 lua_pushinteger(L, n); /* result is integer */ 102 else 103 lua_pushnumber(L, d); /* result is float */ 104 } 105 106 107 static int math_floor (lua_State *L) { 108 if (lua_isinteger(L, 1)) 109 lua_settop(L, 1); /* integer is its own floor */ 110 else { 111 lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1)); 112 pushnumint(L, d); 113 } 114 return 1; 115 } 116 117 118 static int math_ceil (lua_State *L) { 119 if (lua_isinteger(L, 1)) 120 lua_settop(L, 1); /* integer is its own ceil */ 121 else { 122 lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1)); 123 pushnumint(L, d); 124 } 125 return 1; 126 } 127 128 129 static int math_fmod (lua_State *L) { 130 if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { 131 lua_Integer d = lua_tointeger(L, 2); 132 if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */ 133 luaL_argcheck(L, d != 0, 2, "zero"); 134 lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */ 135 } 136 else 137 lua_pushinteger(L, lua_tointeger(L, 1) % d); 138 } 139 else 140 lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), 141 luaL_checknumber(L, 2))); 142 return 1; 143 } 144 145 146 /* 147 ** next function does not use 'modf', avoiding problems with 'double*' 148 ** (which is not compatible with 'float*') when lua_Number is not 149 ** 'double'. 150 */ 151 static int math_modf (lua_State *L) { 152 if (lua_isinteger(L ,1)) { 153 lua_settop(L, 1); /* number is its own integer part */ 154 lua_pushnumber(L, 0); /* no fractional part */ 155 } 156 else { 157 lua_Number n = luaL_checknumber(L, 1); 158 /* integer part (rounds toward zero) */ 159 lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n); 160 pushnumint(L, ip); 161 /* fractional part (test needed for inf/-inf) */ 162 lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); 163 } 164 return 2; 165 } 166 167 168 static int math_sqrt (lua_State *L) { 169 lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); 170 return 1; 171 } 172 173 174 static int math_ult (lua_State *L) { 175 lua_Integer a = luaL_checkinteger(L, 1); 176 lua_Integer b = luaL_checkinteger(L, 2); 177 lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b); 178 return 1; 179 } 180 181 static int math_log (lua_State *L) { 182 lua_Number x = luaL_checknumber(L, 1); 183 lua_Number res; 184 if (lua_isnoneornil(L, 2)) 185 res = l_mathop(log)(x); 186 else { 187 lua_Number base = luaL_checknumber(L, 2); 188 #if !defined(LUA_USE_C89) 189 if (base == l_mathop(2.0)) 190 res = l_mathop(log2)(x); else 191 #endif 192 if (base == l_mathop(10.0)) 193 res = l_mathop(log10)(x); 194 else 195 res = l_mathop(log)(x)/l_mathop(log)(base); 196 } 197 lua_pushnumber(L, res); 198 return 1; 199 } 200 201 static int math_exp (lua_State *L) { 202 lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); 203 return 1; 204 } 205 206 static int math_deg (lua_State *L) { 207 lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI)); 208 return 1; 209 } 210 211 static int math_rad (lua_State *L) { 212 lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0))); 213 return 1; 214 } 215 216 217 static int math_min (lua_State *L) { 218 int n = lua_gettop(L); /* number of arguments */ 219 int imin = 1; /* index of current minimum value */ 220 int i; 221 luaL_argcheck(L, n >= 1, 1, "value expected"); 222 for (i = 2; i <= n; i++) { 223 if (lua_compare(L, i, imin, LUA_OPLT)) 224 imin = i; 225 } 226 lua_pushvalue(L, imin); 227 return 1; 228 } 229 230 231 static int math_max (lua_State *L) { 232 int n = lua_gettop(L); /* number of arguments */ 233 int imax = 1; /* index of current maximum value */ 234 int i; 235 luaL_argcheck(L, n >= 1, 1, "value expected"); 236 for (i = 2; i <= n; i++) { 237 if (lua_compare(L, imax, i, LUA_OPLT)) 238 imax = i; 239 } 240 lua_pushvalue(L, imax); 241 return 1; 242 } 243 244 /* 245 ** This function uses 'double' (instead of 'lua_Number') to ensure that 246 ** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0' 247 ** will keep full precision (ensuring that 'r' is always less than 1.0.) 248 */ 249 static int math_random (lua_State *L) { 250 lua_Integer low, up; 251 double r = (double)l_rand() * (1.0 / ((double)L_RANDMAX + 1.0)); 252 switch (lua_gettop(L)) { /* check number of arguments */ 253 case 0: { /* no arguments */ 254 lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */ 255 return 1; 256 } 257 case 1: { /* only upper limit */ 258 low = 1; 259 up = luaL_checkinteger(L, 1); 260 break; 261 } 262 case 2: { /* lower and upper limits */ 263 low = luaL_checkinteger(L, 1); 264 up = luaL_checkinteger(L, 2); 265 break; 266 } 267 default: return luaL_error(L, "wrong number of arguments"); 268 } 269 /* random integer in the interval [low, up] */ 270 luaL_argcheck(L, low <= up, 1, "interval is empty"); 271 luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1, 272 "interval too large"); 273 r *= (double)(up - low) + 1.0; 274 lua_pushinteger(L, (lua_Integer)r + low); 275 return 1; 276 } 277 278 279 static int math_randomseed (lua_State *L) { 280 l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1)); 281 (void)l_rand(); /* discard first value to avoid undesirable correlations */ 282 return 0; 283 } 284 285 286 static int math_type (lua_State *L) { 287 if (lua_type(L, 1) == LUA_TNUMBER) { 288 if (lua_isinteger(L, 1)) 289 lua_pushliteral(L, "integer"); 290 else 291 lua_pushliteral(L, "float"); 292 } 293 else { 294 luaL_checkany(L, 1); 295 lua_pushnil(L); 296 } 297 return 1; 298 } 299 300 301 /* 302 ** {================================================================== 303 ** Deprecated functions (for compatibility only) 304 ** =================================================================== 305 */ 306 #if defined(LUA_COMPAT_MATHLIB) 307 308 static int math_cosh (lua_State *L) { 309 lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); 310 return 1; 311 } 312 313 static int math_sinh (lua_State *L) { 314 lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); 315 return 1; 316 } 317 318 static int math_tanh (lua_State *L) { 319 lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); 320 return 1; 321 } 322 323 static int math_pow (lua_State *L) { 324 lua_Number x = luaL_checknumber(L, 1); 325 lua_Number y = luaL_checknumber(L, 2); 326 lua_pushnumber(L, l_mathop(pow)(x, y)); 327 return 1; 328 } 329 330 static int math_frexp (lua_State *L) { 331 int e; 332 lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); 333 lua_pushinteger(L, e); 334 return 2; 335 } 336 337 static int math_ldexp (lua_State *L) { 338 lua_Number x = luaL_checknumber(L, 1); 339 int ep = (int)luaL_checkinteger(L, 2); 340 lua_pushnumber(L, l_mathop(ldexp)(x, ep)); 341 return 1; 342 } 343 344 static int math_log10 (lua_State *L) { 345 lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); 346 return 1; 347 } 348 349 #endif 350 /* }================================================================== */ 351 352 353 354 static const luaL_Reg mathlib[] = { 355 {"abs", math_abs}, 356 {"acos", math_acos}, 357 {"asin", math_asin}, 358 {"atan", math_atan}, 359 {"ceil", math_ceil}, 360 {"cos", math_cos}, 361 {"deg", math_deg}, 362 {"exp", math_exp}, 363 {"tointeger", math_toint}, 364 {"floor", math_floor}, 365 {"fmod", math_fmod}, 366 {"ult", math_ult}, 367 {"log", math_log}, 368 {"max", math_max}, 369 {"min", math_min}, 370 {"modf", math_modf}, 371 {"rad", math_rad}, 372 {"random", math_random}, 373 {"randomseed", math_randomseed}, 374 {"sin", math_sin}, 375 {"sqrt", math_sqrt}, 376 {"tan", math_tan}, 377 {"type", math_type}, 378 #if defined(LUA_COMPAT_MATHLIB) 379 {"atan2", math_atan}, 380 {"cosh", math_cosh}, 381 {"sinh", math_sinh}, 382 {"tanh", math_tanh}, 383 {"pow", math_pow}, 384 {"frexp", math_frexp}, 385 {"ldexp", math_ldexp}, 386 {"log10", math_log10}, 387 #endif 388 /* placeholders */ 389 {"pi", NULL}, 390 {"huge", NULL}, 391 {"maxinteger", NULL}, 392 {"mininteger", NULL}, 393 {NULL, NULL} 394 }; 395 396 397 /* 398 ** Open math library 399 */ 400 LUAMOD_API int luaopen_math (lua_State *L) { 401 luaL_newlib(L, mathlib); 402 lua_pushnumber(L, PI); 403 lua_setfield(L, -2, "pi"); 404 lua_pushnumber(L, (lua_Number)HUGE_VAL); 405 lua_setfield(L, -2, "huge"); 406 lua_pushinteger(L, LUA_MAXINTEGER); 407 lua_setfield(L, -2, "maxinteger"); 408 lua_pushinteger(L, LUA_MININTEGER); 409 lua_setfield(L, -2, "mininteger"); 410 return 1; 411 } 412 413