One Level Up
  Top Level
 
  src/lib_math.c - luajit-2.0-src
 Data types defined
 
 Functions defined
 
 Macros defined
 
 Source code
  
 
- #include <math.h>
 
 
- #define lib_math_c
 
- #define LUA_LIB
 
 
- #include "lua.h"
 
- #include "lauxlib.h"
 
- #include "lualib.h"
 
 
- #include "lj_obj.h"
 
- #include "lj_lib.h"
 
- #include "lj_vm.h"
 
 
 
- #define LJLIB_MODULE_math
 
 
- LJLIB_ASM(math_abs)                LJLIB_REC(.)
 
- {
 
-   lj_lib_checknumber(L, 1);
 
-   return FFH_RETRY;
 
- }
 
- LJLIB_ASM_(math_floor)                LJLIB_REC(math_round IRFPM_FLOOR)
 
- LJLIB_ASM_(math_ceil)                LJLIB_REC(math_round IRFPM_CEIL)
 
 
- LJLIB_ASM(math_sqrt)                LJLIB_REC(math_unary IRFPM_SQRT)
 
- {
 
-   lj_lib_checknum(L, 1);
 
-   return FFH_RETRY;
 
- }
 
- LJLIB_ASM_(math_log10)                LJLIB_REC(math_unary IRFPM_LOG10)
 
- LJLIB_ASM_(math_exp)                LJLIB_REC(math_unary IRFPM_EXP)
 
- LJLIB_ASM_(math_sin)                LJLIB_REC(math_unary IRFPM_SIN)
 
- LJLIB_ASM_(math_cos)                LJLIB_REC(math_unary IRFPM_COS)
 
- LJLIB_ASM_(math_tan)                LJLIB_REC(math_unary IRFPM_TAN)
 
- LJLIB_ASM_(math_asin)                LJLIB_REC(math_atrig FF_math_asin)
 
- LJLIB_ASM_(math_acos)                LJLIB_REC(math_atrig FF_math_acos)
 
- LJLIB_ASM_(math_atan)                LJLIB_REC(math_atrig FF_math_atan)
 
- LJLIB_ASM_(math_sinh)                LJLIB_REC(math_htrig IRCALL_sinh)
 
- LJLIB_ASM_(math_cosh)                LJLIB_REC(math_htrig IRCALL_cosh)
 
- LJLIB_ASM_(math_tanh)                LJLIB_REC(math_htrig IRCALL_tanh)
 
- LJLIB_ASM_(math_frexp)
 
- LJLIB_ASM_(math_modf)                LJLIB_REC(.)
 
 
- LJLIB_ASM(math_log)                LJLIB_REC(math_log)
 
- {
 
-   double x = lj_lib_checknum(L, 1);
 
-   if (L->base+1 < L->top) {
 
-     double y = lj_lib_checknum(L, 2);
 
- #ifdef LUAJIT_NO_LOG2
 
-     x = log(x); y = 1.0 / log(y);
 
- #else
 
-     x = lj_vm_log2(x); y = 1.0 / lj_vm_log2(y);
 
- #endif
 
-     setnumV(L->base-1-LJ_FR2, x*y);  
 
-     return FFH_RES(1);
 
-   }
 
-   return FFH_RETRY;
 
- }
 
 
- LJLIB_LUA(math_deg) 
 
- LJLIB_LUA(math_rad) 
 
 
- LJLIB_ASM(math_atan2)                LJLIB_REC(.)
 
- {
 
-   lj_lib_checknum(L, 1);
 
-   lj_lib_checknum(L, 2);
 
-   return FFH_RETRY;
 
- }
 
- LJLIB_ASM_(math_pow)                LJLIB_REC(.)
 
- LJLIB_ASM_(math_fmod)
 
 
- LJLIB_ASM(math_ldexp)                LJLIB_REC(.)
 
- {
 
-   lj_lib_checknum(L, 1);
 
- #if LJ_DUALNUM && !LJ_TARGET_X86ORX64
 
-   lj_lib_checkint(L, 2);
 
- #else
 
-   lj_lib_checknum(L, 2);
 
- #endif
 
-   return FFH_RETRY;
 
- }
 
 
- LJLIB_ASM(math_min)                LJLIB_REC(math_minmax IR_MIN)
 
- {
 
-   int i = 0;
 
-   do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
 
-   return FFH_RETRY;
 
- }
 
- LJLIB_ASM_(math_max)                LJLIB_REC(math_minmax IR_MAX)
 
 
- LJLIB_PUSH(3.14159265358979323846) LJLIB_SET(pi)
 
- LJLIB_PUSH(1e310) LJLIB_SET(huge)
 
 
 
 
- struct RandomState {
 
-   uint64_t gen[4];        
 
-   int valid;                
 
- };
 
 
- typedef union { uint64_t u64; double d; } U64double;
 
 
- #define TW223_GEN(i, k, q, s) \
 
-   z = rs->gen[i]; \
 
-   z = (((z<<q)^z) >> (k-s)) ^ ((z&((uint64_t)(int64_t)-1 << (64-k)))<<s); \
 
-   r ^= z; rs->gen[i] = z;
 
 
- LJ_NOINLINE uint64_t LJ_FASTCALL lj_math_random_step(RandomState *rs)
 
- {
 
-   uint64_t z, r = 0;
 
-   TW223_GEN(0, 63, 31, 18)
 
-   TW223_GEN(1, 58, 19, 28)
 
-   TW223_GEN(2, 55, 24,  7)
 
-   TW223_GEN(3, 47, 21,  8)
 
-   return (r & U64x(000fffff,ffffffff)) | U64x(3ff00000,00000000);
 
- }
 
 
- static void random_init(RandomState *rs, double d)
 
- {
 
-   uint32_t r = 0x11090601;  
 
-   int i;
 
-   for (i = 0; i < 4; i++) {
 
-     U64double u;
 
-     uint32_t m = 1u << (r&255);
 
-     r >>= 8;
 
-     u.d = d = d * 3.14159265358979323846 + 2.7182818284590452354;
 
-     if (u.u64 < m) u.u64 += m;  
 
-     rs->gen[i] = u.u64;
 
-   }
 
-   rs->valid = 1;
 
-   for (i = 0; i < 10; i++)
 
-     lj_math_random_step(rs);
 
- }
 
 
- LJLIB_PUSH(top-2)  
 
- LJLIB_CF(math_random)                LJLIB_REC(.)
 
- {
 
-   int n = (int)(L->top - L->base);
 
-   RandomState *rs = (RandomState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
 
-   U64double u;
 
-   double d;
 
-   if (LJ_UNLIKELY(!rs->valid)) random_init(rs, 0.0);
 
-   u.u64 = lj_math_random_step(rs);
 
-   d = u.d - 1.0;
 
-   if (n > 0) {
 
- #if LJ_DUALNUM
 
-     int isint = 1;
 
-     double r1;
 
-     lj_lib_checknumber(L, 1);
 
-     if (tvisint(L->base)) {
 
-       r1 = (lua_Number)intV(L->base);
 
-     } else {
 
-       isint = 0;
 
-       r1 = numV(L->base);
 
-     }
 
- #else
 
-     double r1 = lj_lib_checknum(L, 1);
 
- #endif
 
-     if (n == 1) {
 
-       d = lj_vm_floor(d*r1) + 1.0;  
 
-     } else {
 
- #if LJ_DUALNUM
 
-       double r2;
 
-       lj_lib_checknumber(L, 2);
 
-       if (tvisint(L->base+1)) {
 
-         r2 = (lua_Number)intV(L->base+1);
 
-       } else {
 
-         isint = 0;
 
-         r2 = numV(L->base+1);
 
-       }
 
- #else
 
-       double r2 = lj_lib_checknum(L, 2);
 
- #endif
 
-       d = lj_vm_floor(d*(r2-r1+1.0)) + r1;  
 
-     }
 
- #if LJ_DUALNUM
 
-     if (isint) {
 
-       setintV(L->top-1, lj_num2int(d));
 
-       return 1;
 
-     }
 
- #endif
 
-   }  
 
-   setnumV(L->top++, d);
 
-   return 1;
 
- }
 
 
- LJLIB_PUSH(top-2)  
 
- LJLIB_CF(math_randomseed)
 
- {
 
-   RandomState *rs = (RandomState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
 
-   random_init(rs, lj_lib_checknum(L, 1));
 
-   return 0;
 
- }
 
 
 
- #include "lj_libdef.h"
 
 
- LUALIB_API int luaopen_math(lua_State *L)
 
- {
 
-   RandomState *rs;
 
-   rs = (RandomState *)lua_newuserdata(L, sizeof(RandomState));
 
-   rs->valid = 0;  
 
-   LJ_LIB_REG(L, LUA_MATHLIBNAME, math);
 
- #if defined(LUA_COMPAT_MOD) && !LJ_52
 
-   lua_getfield(L, -1, "fmod");
 
-   lua_setfield(L, -2, "mod");
 
- #endif
 
-   return 1;
 
- }
 
 
 
  One Level Up
  Top Level