在LuaForge中提供bitlib可以在lua5.1版本中提高为操作符运算。bitlib通过c语言来实现跨平台位操作符。
Lua functions provided:
bit.bnot(a) returns the one's complement of a
bit.band(w1,...) returns the bitwise and of the w's
bit.bor(w1,...) returns the bitwise or of the w's
bit.bxor(w1,...) returns the bitwise exclusive or of the w's
bit.lshift(a,b) returns a shifted left b places
bit.rshift(a,b) returns a shifted logically right b places
bit.arshift(a,b) returns a shifted arithmetically right b places
bit.mod(a,b) returns the integer remainder of a divided by b
All function arguments should be integers.
The number of bits available for logical operations depends on the data type used to represent Lua numbers;
this is typically 8-byte IEEE floats, which give 53 bits (the size of the mantissa).
在bitlib中所有位操作的参数为整数。
位操作中有效位数依赖于LUA Number的实现。IEEE中8 btye floats 仅仅有53位有效位数。
#include "lauxlib.h"
#include "lua.h"
typedef long long Integer;
typedef unsigned long long UInteger;
#define luaL_checkbit(L, n) ((Integer)luaL_checknumber(L, n)) //定义可以操作的最大整数。会依赖于LUA Number
#define luaL_checkubit(L, n) ((UInteger)luaL_checkbit(L, n)) //在实现中可以操作64bit,但是最大有效位数依赖于LUA Number的实现
#define TDYADIC(name, op, checkbit1, checkbit2) \
static int bit_ ## name(lua_State* L) { \
lua_pushnumber(L, \
checkbit1(L, 1) op checkbit2(L, 2)); \ //通过c语言提供的移位运算符直接移位
return 1; \
}
#define DYADIC(name, op) \
TDYADIC(name, op, luaL_checkbit, luaL_checkbit)
#define MONADIC(name, op) \
static int bit_ ## name(lua_State* L) { \
lua_pushnumber(L, op luaL_checkbit(L, 1)); \ //直接取反位运算
return 1; \
}
#define VARIADIC(name, op) \
static int bit_ ## name(lua_State *L) { \
int n = lua_gettop(L), i; \
Integer w = luaL_checkbit(L, 1); \
for (i = 2; i <= n; i++) \
w op luaL_checkbit(L, i); \ //可以实现可变参数的复合位运算&=、|=、^=
lua_pushnumber(L, w); \
return 1; \
}
MONADIC(bnot, ~)
VARIADIC(band, &=)
VARIADIC(bor, |=)
VARIADIC(bxor, ^=)
TDYADIC(lshift, <<, luaL_checkbit, luaL_checkubit)
TDYADIC(rshift, >>, luaL_checkubit, luaL_checkubit)
TDYADIC(arshift, >>, luaL_checkbit, luaL_checkubit)
DYADIC(mod, %)
static const struct luaL_reg bitlib[] = {
{"bnot", bit_bnot},
{"band", bit_band},
{"bor", bit_bor},
{"bxor", bit_bxor},
{"lshift", bit_lshift},
{"rshift", bit_rshift},
{"arshift", bit_arshift},
{"mod", bit_mod},
{NULL, NULL}
};
LUALIB_API int luaopen_bit (lua_State *L) {
luaL_openlib(L, "bit", bitlib, 0);
return 1;
}