LCOV - code coverage report
Current view: top level - AP_Scripting/lua/src - lmathlib.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 159 159 100.0 %
Date: 2026-09-09 11:02:08 Functions: 25 25 100.0 %

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

Generated by: LCOV version 1.14