lmathlib.c 10 KB

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