Created
April 2, 2016 20:13
-
-
Save pablomayobre/41acbf4918ad4465c4cc8e151d940a81 to your computer and use it in GitHub Desktop.
Bite is a common bit operations interface that uses BitOps, bit32, Lua 5.3 bit operators or plain Lua bit operations (The api is the same as BitOps plus some functions from bit32)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local bit = {} | |
local normalize = function (...) | |
local t = {} | |
for k,v in ipairs{...} do | |
t[k] = v <= 0x7fffffff and v or -(bit.bnot(v) + 1) | |
end | |
end | |
--LuaJIT BitOp library | |
local ok, bit = pcall(require, "bit") | |
if ok then | |
bit.bswap, bit.tohex = nil,nil | |
end | |
--Lua 5.2 bit32 library | |
if not ok then | |
ok, bit = pcall(require, "bit32") | |
if ok then | |
bit.replace, bit.extract, bit.btest = nil,nil,nil | |
bit.tobit = function (a) | |
return bit.bnot(bit.bnot(a)) | |
end | |
bit.rol = bit.lrotate | |
bit.ror = bit.rrotate | |
local _oldlshift, _oldrshift _oldarshift = bit.lshift, bit.rshift, bit.arshift | |
bit.lshift = function (a,disp) | |
local disp = disp % 32 | |
return _oldlshift(a,disp) | |
end | |
bit.rshift = function (a,disp) | |
local disp = disp % 32 | |
return _oldrshift(a,disp) | |
end | |
bit.arshift = function (a,disp) | |
local disp = disp % 32 | |
return _oldarshift(a,disp) | |
end | |
for k,v in pairs(bit) do | |
bit[k] = function (...) return normalize(v(...)) end | |
end | |
end | |
end | |
--Pure Lua implementation | |
if _VERSION == "Lua 5.3" then | |
local s = [[ | |
local bit = {} | |
bit.tobit = function (a) | |
return math.tointeger(a) & 0xffffffff | |
end | |
bit.bnot = function (a) | |
return (~a) & 0xffffffff | |
end | |
local bxor,band,bor | |
bxor = function (a,b,...) | |
if b == nil then return a end | |
local c = (a ~ b) & 0xffffffff | |
return bxor(c,...) | |
end | |
band = function (a,b,...) | |
if b == nil then return a end | |
local c = (a & b) & 0xffffffff | |
return band(c,...) | |
end | |
bor = function (a,b,...) | |
if b == nil then return a end | |
local c = (a | b) & 0xffffffff | |
return bor(c,...) | |
end | |
bit.bxor = bxor | |
bit.band = band | |
bit.bor = bor | |
bit.rshift = function (a,disp) | |
local disp = math.tointeger(disp % 32) | |
return (a >> disp) & 0xffffffff | |
end | |
bit.lshift = function (a,disp) | |
local disp = math.tointeger(disp % 32) | |
return (a << disp) & 0xffffffff | |
end | |
bit.arshift = function (a,disp) | |
local disp = math.integer(disp % 32) | |
local a = math.tointeger(a) & 0xffffffff | |
if a == 0 then return a end | |
if disp > 0 then | |
local s = a > 0 and 1 or -1 | |
local b = a > 0 and 0 or 1 | |
return (s * (math.abs(a) >> disp) - b) & 0xffffffff | |
elseif disp < 0 then | |
return (a << disp) & 0xffffffff | |
else | |
return a | |
end | |
end | |
bit.ror = function () | |
local disp = math.tointeger(disp % 32) | |
if a == 0 or disp == 0 then return a end | |
local a = math.tointeger(a) & 0xffffffff | |
local b,c = a << (31 - disp), a >> disp | |
return math.tointeger(b) + math.tointeger(c) | |
end | |
bit.rol = function () | |
local disp = math.tointeger(disp % 32) | |
if a == 0 or disp == 0 then return a end | |
local a = math.tointeger(a) & 0xffffffff | |
local b,c = a << disp, a >> (31 - disp) | |
return math.tointeger(b) + math.tointeger(c) | |
end | |
for k,v in pairs(bit) do | |
bit[k] = function (...) return normalize(v(...)) end | |
end | |
return bit | |
]] | |
local err | |
ok,err = load(s,"bit","t") | |
if ok then | |
bit = ok() | |
end | |
end | |
if not ok then | |
bit = {} | |
bit.tobit = function (a) | |
return math.floor(a) % (0xffffffff + 1) | |
end | |
local xort = {{0,1},{1,0}} | |
local andt = {{0,0},{0,1}} | |
local ort = {{0,1},{1,1}} | |
local master | |
master = function (t,a,b,...) | |
if b == nil then return a end | |
local a,b = bit.tobit(a),bit.tobit(b) | |
local pow = 1 | |
local c = 0 | |
while a > 0 or b > 0 do | |
c = c + (t[(a % 2)+1][(b % 2)+1] * pow) | |
a = math.floor(a/2) | |
b = math.floor(b/2) | |
pow = pow * 2 | |
end | |
return master(t,c,...) | |
end | |
bit.bnot = function (x) | |
local x = bit.tobit(x) | |
return bit.tobit((-1 - x) % 2^32) | |
end | |
bit.bxor = function (...) | |
return bit.tobit(master(xort,...)) | |
end | |
bit.band = function (...) | |
return bit.tobit(master(andt,...)) | |
end | |
bit.bor = function (...) | |
return bit.tobit(master(ort,...)) | |
end | |
bit.lshift = function (a,disp) | |
local disp = math.floor(disp % 32) | |
if a == 0 or disp == 0 then return a end | |
local a = bit.tobit(a) | |
return bit.tobit(a * 2 ^ disp) | |
end | |
bit.rshift = function (a,disp) | |
local disp = math.floor(disp % 32) | |
if a == 0 or disp == 0 then return a end | |
local a = bit.tobit(a) | |
return bit.tobit(math.floor(a / 2 ^ disp)) | |
end | |
bit.arshift = function (a,disp) | |
local disp = math.floor(disp % 32) | |
if a == 0 then return a end | |
local a = bit.tobit(a) | |
if disp > 0 then | |
local s = a > 0 and 1 or -1 | |
local b = a > 0 and 0 or 1 | |
return bit.tobit(s * (math.abs(a) / 2 ^ disp) - b) | |
elseif disp < 0 then | |
return bit.tobit(a * 2 ^ disp) | |
else | |
return a | |
end | |
end | |
bit.ror = function (a,disp) | |
local disp = math.floor(disp % 32) | |
if a == 0 or disp == 0 then return a end | |
local a = bit.tobit(a) | |
local b,c = a * 2 ^ (31 - disp), a / 2 ^ disp | |
return bit.tobit(bit.tobit(b) + bit.tobit(c)) | |
end | |
bit.rol = function (a,disp) | |
local disp = math.floor(31 - (disp % 32)) | |
if a == 0 or disp == 0 then return a end | |
return bit.ror(a,disp) | |
end | |
for k,v in pairs(bit) do | |
bit[k] = function (...) return normalize(v(...)) end | |
end | |
end | |
return bit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment