zombiezen.com/go/lua@v0.0.0-20231013005828-290725fb9140/internal/lua54/lmathlib.c (about)

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