这里是用 c 写了一个随机数模块,供 lua 使用。算是一个模板,供参考。
#include
#include
#include
#include
#include
#include
#define LRANDOM_RAND_MAX 32767
static const char *libName = "lrand";
typedef struct LRandom {
unsigned long int next;
}LRandom, *LRandomPtr;
static int gen(LRandomPtr p) {
p->next = p->next * 1103515245 + 12345;
return ((unsigned)(p->next / 65536) % LRANDOM_RAND_MAX);
}
static LRandomPtr checkLRandom(lua_State *L, int index) {
void *ud = luaL_checkudata(L, index, libName);
luaL_argcheck(L, NULL != ud, index, "LRandom expected");
return (LRandomPtr)ud;
}
static int lnew(lua_State *L) {
unsigned long int seed = 1;
int n = lua_gettop(L);
if (0 != n) {
seed = (unsigned long int)luaL_checkinteger(L, 1);
}
LRandomPtr p = (LRandomPtr)lua_newuserdata(L, sizeof(LRandom));
p->next = seed;
luaL_getmetatable(L, libName);
lua_setmetatable(L, -2);
return 1;
}
static int lrand(lua_State *L) {
LRandomPtr p = checkLRandom(L, 1);
int num = gen(p);
lua_pushinteger(L, num);
return 1;
}
static int lnext(lua_State *L) {
lua_Integer low, up;
LRandomPtr p = checkLRandom(L, 1);
double r = (double)gen(p) * (1.0 / (double)(LRANDOM_RAND_MAX + 1.0));
int n = lua_gettop(L);
switch (n) {
case 1: {
lua_pushnumber(L, r);
return 1;
}
case 2: {
low = 1;
up = luaL_checkinteger(L, 2);
break;
}
case 3: {
low = luaL_checkinteger(L, 2);
up = luaL_checkinteger(L, 3);
break;
}
default:
return luaL_error(L, "wrong number of arguments");
}
luaL_argcheck(L, low = 0 || up <= LUA_MAXINTEGER + low, 2, "inteval too large");
r *= (double)(up - low) + 1.0;
lua_pushinteger(L, (lua_Integer)r + low);
return 1;
}
int luaopen_lrand(lua_State *L) {
const luaL_Reg l_f[] = {
{ "new", lnew },
{ "rand", lrand },
{ "next", lnext },
{ NULL, NULL }
};
const luaL_Reg l_m[] = {
{ "rand", lrand },
{ "next", lnext },
{ NULL, NULL }
};
luaL_newmetatable(L, libName);
lua_pushstring(L, "__index");
lua_pushvalue(L, -2);
lua_rawset(L, -3);
luaL_setfuncs(L, l_m, 0);
luaL_newlib(L, l_f);
return 1;
}
作者:maqqme