lmtxmathlib.c /size: 12 Kb    last modification: 2024-01-16 10:22
1/*
2
3    See license.txt in the root of this project.
4
5    This is a reformatted and slightly adapted version of lmathx.c:
6
7    title  : C99 math functions for Lua 5.3+
8    author : Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br>
9    date   : 24 Jun 2015 09:51:50
10    licence: This code is hereby placed in the public domain.
11
12    In the end I just expanded and adapted the code a bit which made it easier to get rid of some
13    compiler warnings (if possible at all).
14
15*/
16
17# include "luametatex.h"
18
19# include <math.h>
20
21# define xmathlib_pi  ((lua_Number)(3.141592653589793238462643383279502884))
22# define xmathlib_180 ((lua_Number) 180.0)
23# define xmathlib_inf ((lua_Number) INFINITY)
24# define xmathlib_nan ((lua_Number) NAN)
25
26static int xmathlib_acos(lua_State *L)
27{
28    lua_pushnumber(L, (lua_Number) acos(luaL_checknumber(L, 1)));
29    return 1;
30}
31
32static int xmathlib_acosh(lua_State *L)
33{
34    lua_pushnumber(L, (lua_Number) acosh(luaL_checknumber(L, 1)));
35    return 1;
36}
37
38static int xmathlib_asin(lua_State *L)
39{
40    lua_pushnumber(L, (lua_Number) asin(luaL_checknumber(L, 1)));
41    return 1;
42}
43
44static int xmathlib_asinh(lua_State *L)
45{
46    lua_pushnumber(L, (lua_Number) asinh(luaL_checknumber(L, 1)));
47    return 1;
48}
49
50static int xmathlib_atan(lua_State *L)
51{
52    if (lua_gettop(L) == 1) {
53        lua_pushnumber(L, (lua_Number) atan(luaL_checknumber(L, 1)));
54    } else {
55        lua_pushnumber(L, (lua_Number) atan2(luaL_checknumber(L, 1),luaL_checknumber(L, 2)));
56    }
57    return 1;
58}
59
60static int xmathlib_atan2(lua_State *L)
61{
62    lua_pushnumber(L, (lua_Number) atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
63    return 1;
64}
65
66static int xmathlib_atanh(lua_State *L)
67{
68    lua_pushnumber(L, (lua_Number) atanh(luaL_checknumber(L, 1)));
69    return 1;
70}
71
72static int xmathlib_cbrt(lua_State *L)
73{
74    lua_pushnumber(L, (lua_Number) cbrt(luaL_checknumber(L, 1)));
75    return 1;
76}
77
78static int xmathlib_ceil(lua_State *L)
79{
80    lua_pushnumber(L, (lua_Number) ceil(luaL_checknumber(L, 1)));
81    return 1;
82}
83
84static int xmathlib_copysign (lua_State *L)
85{
86    lua_pushnumber(L, (lua_Number) copysign(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
87    return 1;
88}
89
90static int xmathlib_cos(lua_State *L)
91{
92    lua_pushnumber(L, (lua_Number) cos(luaL_checknumber(L, 1)));
93    return 1;
94}
95
96static int xmathlib_cosh(lua_State *L)
97{
98    lua_pushnumber(L, (lua_Number) cosh(luaL_checknumber(L, 1)));
99    return 1;
100}
101
102static int xmathlib_deg(lua_State *L)
103{
104    lua_pushnumber(L, luaL_checknumber(L, 1) * (xmathlib_180 / xmathlib_pi));
105    return 1;
106}
107
108static int xmathlib_erf(lua_State *L)
109{
110    lua_pushnumber(L, (lua_Number) erf(luaL_checknumber(L, 1)));
111    return 1;
112}
113
114static int xmathlib_erfc(lua_State *L)
115{
116    lua_pushnumber(L, (lua_Number) erfc(luaL_checknumber(L, 1)));
117    return 1;
118}
119
120static int xmathlib_exp(lua_State *L)
121{
122    lua_pushnumber(L, (lua_Number) exp(luaL_checknumber(L, 1)));
123    return 1;
124}
125
126static int xmathlib_exp2(lua_State *L)
127{
128    lua_pushnumber(L, (lua_Number) exp2(luaL_checknumber(L, 1)));
129    return 1;
130}
131
132static int xmathlib_expm1(lua_State *L)
133{
134    lua_pushnumber(L, (lua_Number) expm1(luaL_checknumber(L, 1)));
135    return 1;
136}
137
138static int xmathlib_fabs(lua_State *L)
139{
140    lua_pushnumber(L, (lua_Number) fabs(luaL_checknumber(L, 1)));
141    return 1;
142}
143
144static int xmathlib_fdim(lua_State *L)
145{
146    lua_pushnumber(L, (lua_Number) fdim(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
147    return 1;
148}
149
150static int xmathlib_floor(lua_State *L)
151{
152    lua_pushnumber(L, (lua_Number) floor(luaL_checknumber(L, 1)));
153    return 1;
154}
155
156static int xmathlib_fma(lua_State *L)
157{
158    lua_pushnumber(L, (lua_Number) fma(luaL_checknumber(L, 1), luaL_checknumber(L, 2), luaL_checknumber(L, 3)));
159    return 1;
160}
161
162static int xmathlib_fmax(lua_State *L)
163{
164    int n = lua_gettop(L);
165    lua_Number m = luaL_checknumber(L, 1);
166    for (int i = 2; i <= n; i++) {
167        m = (lua_Number) fmax(m, luaL_checknumber(L, i));
168    }
169    lua_pushnumber(L, m);
170    return 1;
171}
172
173static int xmathlib_fmin(lua_State *L)
174{
175    int n = lua_gettop(L);
176    lua_Number m = luaL_checknumber(L, 1);
177    for (int i = 2; i <= n; i++) {
178        m = (lua_Number) fmin(m, luaL_checknumber(L, i));
179    }
180    lua_pushnumber(L, m);
181    return 1;
182}
183
184static int xmathlib_fmod(lua_State *L)
185{
186    lua_pushnumber(L, (lua_Number) fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
187    return 1;
188}
189
190static int xmathlib_frexp(lua_State *L)
191{
192    int e;
193    lua_pushnumber(L, (lua_Number) frexp(luaL_checknumber(L, 1), &e));
194    lua_pushinteger(L, e);
195    return 2;
196}
197static int xmathlib_fremquo(lua_State *L)
198{
199    int e;
200    lua_pushnumber(L, (lua_Number) remquo(luaL_checknumber(L, 1),luaL_checknumber(L, 2), &e));
201    lua_pushinteger(L, e);
202    return 2;
203}
204
205static int xmathlib_gamma(lua_State *L)
206{
207    lua_pushnumber(L, (lua_Number) tgamma(luaL_checknumber(L, 1)));
208    return 1;
209}
210
211static int xmathlib_hypot(lua_State *L)
212{
213    lua_pushnumber(L, hypot(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
214    return 1;
215}
216
217static int xmathlib_isfinite(lua_State *L)
218{
219    lua_pushboolean(L, isfinite(luaL_checknumber(L, 1)));
220    return 1;
221}
222
223static int xmathlib_isinf(lua_State *L)
224{
225    lua_pushboolean(L, isinf(luaL_checknumber(L, 1)));
226    return 1;
227}
228
229static int xmathlib_isnan(lua_State *L)
230{
231    lua_pushboolean(L, isnan(luaL_checknumber(L, 1)));
232    return 1;
233}
234
235static int xmathlib_isnormal (lua_State *L)
236{
237    lua_pushboolean(L, isnormal(luaL_checknumber(L, 1)));
238    return 1;
239}
240
241static int xmathlib_j0(lua_State *L)
242{
243    lua_pushnumber(L, (lua_Number) j0(luaL_checknumber(L, 1)));
244    return 1;
245}
246
247static int xmathlib_j1(lua_State *L)
248{
249    lua_pushnumber(L, (lua_Number) j1(luaL_checknumber(L, 1)));
250    return 1;
251}
252
253static int xmathlib_jn(lua_State *L)
254{
255    lua_pushnumber(L, (lua_Number) jn((int) luaL_checkinteger(L, 1), luaL_checknumber(L, 2)));
256    return 1;
257}
258
259static int xmathlib_ldexp(lua_State *L)
260{
261    lua_pushnumber(L, (lua_Number) ldexp(luaL_checknumber(L, 1), (int) luaL_checkinteger(L, 2)));
262    return 1;
263}
264
265static int xmathlib_lgamma(lua_State *L)
266{
267    lua_pushnumber (L, (lua_Number) lgamma(luaL_checknumber(L, 1)));
268    return 1;
269}
270
271static int xmathlib_log(lua_State *L)
272{
273    if (lua_gettop(L) == 1) {
274        lua_pushnumber(L, (lua_Number) log(luaL_checknumber(L, 1)));
275    } else {
276        lua_Number n = luaL_checknumber(L, 2);
277        if (n == 10.0) {
278            n = (lua_Number) log10(luaL_checknumber(L, 1));
279        } else if (n == 2.0) {
280            n = (lua_Number) log2(luaL_checknumber(L, 1));
281        } else {
282            n = (lua_Number) log(luaL_checknumber(L, 1)) / (lua_Number) log(n);
283        }
284        lua_pushnumber(L, n);
285    }
286    return 1;
287}
288
289static int xmathlib_log10(lua_State *L)
290{
291    lua_pushnumber(L, (lua_Number) log10(luaL_checknumber(L, 1)));
292    return 1;
293}
294
295static int xmathlib_log1p(lua_State *L)
296{
297    lua_pushnumber(L, (lua_Number) log1p(luaL_checknumber(L, 1)));
298    return 1;
299}
300
301static int xmathlib_log2(lua_State *L)
302{
303    lua_pushnumber(L, (lua_Number) log2(luaL_checknumber(L, 1)));
304    return 1;
305}
306
307static int xmathlib_logb(lua_State *L)
308{
309    lua_pushnumber(L, (lua_Number) logb(luaL_checknumber(L, 1)));
310    return 1;
311}
312
313static int xmathlib_modf(lua_State *L)
314{
315    lua_Number ip;
316    lua_Number fp = (lua_Number) modf(luaL_checknumber(L, 1), &ip);
317    lua_pushnumber(L, ip);
318    lua_pushnumber(L, fp);
319    return 2;
320}
321
322static int xmathlib_nearbyint(lua_State *L)
323{
324    lua_pushnumber(L, (lua_Number) nearbyint(luaL_checknumber(L, 1)));
325    return 1;
326}
327
328static int xmathlib_nextafter(lua_State *L)
329{
330    lua_pushnumber(L, (lua_Number) nextafter(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
331    return 1;
332}
333
334static int xmathlib_pow(lua_State *L)
335{
336    lua_pushnumber(L, (lua_Number) pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
337    return 1;
338}
339
340static int xmathlib_rad(lua_State *L)
341{
342   lua_pushnumber(L, (luaL_checknumber(L, 1) * (xmathlib_pi / xmathlib_180)));
343   return 1;
344}
345
346static int xmathlib_remainder(lua_State *L)
347{
348    lua_pushnumber(L, (lua_Number) remainder(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
349    return 1;
350}
351
352static int xmathlib_round(lua_State *L)
353{
354    lua_pushinteger(L, lround(luaL_checknumber(L, 1)));
355    return 1;
356}
357
358static int xmathlib_scalbn(lua_State *L)
359{
360    lua_pushnumber(L, (lua_Number) scalbn(luaL_checknumber(L, 1), (int) luaL_checkinteger(L, 2)));
361    return 1;
362}
363
364static int xmathlib_sin(lua_State *L)
365{
366    lua_pushnumber(L, (lua_Number) sin(luaL_checknumber(L, 1)));
367    return 1;
368}
369
370static int xmathlib_sinh(lua_State *L)
371{
372    lua_pushnumber(L, (lua_Number) sinh(luaL_checknumber(L, 1)));
373    return 1;
374}
375
376static int xmathlib_sqrt(lua_State *L)
377{
378    lua_pushnumber(L, (lua_Number) sqrt(luaL_checknumber(L, 1)));
379    return 1;
380}
381
382static int xmathlib_tan(lua_State *L)
383{
384    lua_pushnumber(L, (lua_Number) tan(luaL_checknumber(L, 1)));
385    return 1;
386}
387
388static int xmathlib_tanh(lua_State *L)
389{
390    lua_pushnumber(L, (lua_Number) tanh(luaL_checknumber(L, 1)));
391    return 1;
392}
393
394static int xmathlib_tgamma(lua_State *L)
395{
396    lua_pushnumber(L, (lua_Number) tgamma(luaL_checknumber(L, 1)));
397    return 1;
398}
399
400static int xmathlib_trunc(lua_State *L)
401{
402    lua_pushnumber(L, (lua_Number) trunc(luaL_checknumber(L, 1)));
403    return 1;
404}
405
406static int xmathlib_y0(lua_State *L)
407{
408    lua_pushnumber(L, (lua_Number) y0(luaL_checknumber(L, 1)));
409    return 1;
410}
411
412static int xmathlib_y1(lua_State *L)
413{
414    lua_pushnumber(L, y1(luaL_checknumber(L, 1)));
415    return 1;
416}
417
418static int xmathlib_yn(lua_State *L)
419{
420    lua_pushnumber(L, yn((int) luaL_checkinteger(L, 1), luaL_checknumber(L, 2)));
421    return 1;
422}
423
424static const luaL_Reg xmathlib_function_list[] =
425{
426    { "acos",      xmathlib_acos      },
427    { "acosh",     xmathlib_acosh     },
428    { "asin",      xmathlib_asin      },
429    { "asinh",     xmathlib_asinh     },
430    { "atan",      xmathlib_atan      },
431    { "atan2",     xmathlib_atan2     },
432    { "atanh",     xmathlib_atanh     },
433    { "cbrt",      xmathlib_cbrt      },
434    { "ceil",      xmathlib_ceil      },
435    { "copysign",  xmathlib_copysign  },
436    { "cos",       xmathlib_cos       },
437    { "cosh",      xmathlib_cosh      },
438    { "deg",       xmathlib_deg       },
439    { "erf",       xmathlib_erf       },
440    { "erfc",      xmathlib_erfc      },
441    { "exp",       xmathlib_exp       },
442    { "exp2",      xmathlib_exp2      },
443    { "expm1",     xmathlib_expm1     },
444    { "fabs",      xmathlib_fabs      },
445    { "fdim",      xmathlib_fdim      },
446    { "floor",     xmathlib_floor     },
447    { "fma",       xmathlib_fma       },
448    { "fmax",      xmathlib_fmax      },
449    { "fmin",      xmathlib_fmin      },
450    { "fmod",      xmathlib_fmod      },
451    { "frexp",     xmathlib_frexp     },
452    { "gamma",     xmathlib_gamma     },
453    { "hypot",     xmathlib_hypot     },
454    { "isfinite",  xmathlib_isfinite  },
455    { "isinf",     xmathlib_isinf     },
456    { "isnan",     xmathlib_isnan     },
457    { "isnormal",  xmathlib_isnormal  },
458    { "j0",        xmathlib_j0        },
459    { "j1",        xmathlib_j1        },
460    { "jn",        xmathlib_jn        },
461    { "ldexp",     xmathlib_ldexp     },
462    { "lgamma",    xmathlib_lgamma    },
463    { "log",       xmathlib_log       },
464    { "log10",     xmathlib_log10     },
465    { "log1p",     xmathlib_log1p     },
466    { "log2",      xmathlib_log2      },
467    { "logb",      xmathlib_logb      },
468    { "modf",      xmathlib_modf      },
469    { "nearbyint", xmathlib_nearbyint },
470    { "nextafter", xmathlib_nextafter },
471    { "pow",       xmathlib_pow       },
472    { "rad",       xmathlib_rad       },
473    { "remainder", xmathlib_remainder },
474    { "remquo",    xmathlib_fremquo   },
475    { "round",     xmathlib_round     },
476    { "scalbn",    xmathlib_scalbn    },
477    { "sin",       xmathlib_sin       },
478    { "sinh",      xmathlib_sinh      },
479    { "sqrt",      xmathlib_sqrt      },
480    { "tan",       xmathlib_tan       },
481    { "tanh",      xmathlib_tanh      },
482    { "tgamma",    xmathlib_tgamma    },
483    { "trunc",     xmathlib_trunc     },
484    { "y0",        xmathlib_y0        },
485    { "y1",        xmathlib_y1        },
486    { "yn",        xmathlib_yn        },
487    { NULL,        NULL               },
488};
489
490int luaopen_xmath(lua_State *L)
491{
492    luaL_newlib(L, xmathlib_function_list);
493    lua_pushnumber(L, xmathlib_inf);
494    lua_setfield(L, -2, "inf");
495    lua_pushnumber(L, xmathlib_nan);
496    lua_setfield(L, -2, "nan");
497    lua_pushnumber(L, xmathlib_pi);
498    lua_setfield(L, -2, "pi");
499    return 1;
500}
501