140 lines
2.1 KiB
Lua
140 lines
2.1 KiB
Lua
-- These are super slow 32-bit operations --
|
|
|
|
local two31 = 2^31
|
|
local two32 = 2^32
|
|
|
|
local to_binary = function(x)
|
|
local pos = two31
|
|
local a = ""
|
|
if x < 0 then
|
|
x = x + two32
|
|
end
|
|
x = x % two32
|
|
for i=1,32 do
|
|
if x >= pos then
|
|
a = a .. "1"
|
|
x = x - pos
|
|
else
|
|
a = a .. "0"
|
|
end
|
|
pos = pos / 2
|
|
end
|
|
return a
|
|
end
|
|
|
|
local from_binary = function(x)
|
|
local z = tonumber(x,2)
|
|
if z >= two31 then
|
|
return z - two32
|
|
else
|
|
return z
|
|
end
|
|
end
|
|
|
|
|
|
local band = function(...)
|
|
local a = {}
|
|
local arg = {...}
|
|
for i = 1,#arg do
|
|
a[i] = to_binary(arg[i])
|
|
end
|
|
local c = ""
|
|
for i = 1,32 do
|
|
local value = true
|
|
for j = 1,#arg do
|
|
if a[j]:sub(i,i) == "0" then
|
|
value = false
|
|
break
|
|
end
|
|
end
|
|
|
|
if value then
|
|
c = c .. "1"
|
|
else
|
|
c = c .. "0"
|
|
end
|
|
end
|
|
return from_binary(c)
|
|
end
|
|
|
|
local bor = function(...)
|
|
local a = {}
|
|
local arg = {...}
|
|
for i = 1,#arg do
|
|
a[i] = to_binary(arg[i])
|
|
end
|
|
local c = ""
|
|
for i = 1,32 do
|
|
local value = false
|
|
for j = 1,#arg do
|
|
if a[j]:sub(i,i) == "1" then
|
|
value = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if value then
|
|
c = c .. "1"
|
|
else
|
|
c = c .. "0"
|
|
end
|
|
end
|
|
return from_binary(c)
|
|
end
|
|
|
|
local bxor = function(...)
|
|
local a = {}
|
|
local arg = {...}
|
|
for i = 1,#arg do
|
|
a[i] = to_binary(arg[i])
|
|
end
|
|
local c = ""
|
|
for i = 1,32 do
|
|
local value = false
|
|
for j = 1,#arg do
|
|
if a[j]:sub(i,i) == "1" then
|
|
value = not value
|
|
end
|
|
end
|
|
|
|
if value then
|
|
c = c .. "1"
|
|
else
|
|
c = c .. "0"
|
|
end
|
|
end
|
|
return from_binary(c)
|
|
end
|
|
|
|
|
|
local bnot = function(x)
|
|
local a = to_binary(x)
|
|
local c = ""
|
|
for i = 1,32 do
|
|
if a:sub(i,i) == "0" then
|
|
c = c .. "1"
|
|
else
|
|
c = c .. "0"
|
|
end
|
|
end
|
|
return from_binary(c)
|
|
end
|
|
|
|
local lshift = function(x,n)
|
|
return (x * 2^n) % two32
|
|
end
|
|
|
|
local rshift = function(x,n)
|
|
return math.floor(x / 2^n)
|
|
end
|
|
|
|
local rol = function(x,n)
|
|
local a = to_binary(x)
|
|
for i = 1,n do
|
|
a = a:sub(2,32) .. a:sub(1,1)
|
|
end
|
|
return from_binary(a)
|
|
end
|
|
|
|
return {rol=rol, bxor=bxor, bor=bor, band=band, bnot=bnot, lshift=lshift, rshift=rshift}
|