Files
HyperionOS/Src/Hyperion-core/lib/bit32
2026-01-18 22:14:15 -05:00

138 lines
2.7 KiB
Plaintext

--:Minify:--
local bit32 = {}
local MOD32 = 2^32
local MOD31 = 2^31
local function norm(x)
return x % MOD32
end
-- Convert number to bit table
local function tobits(x)
x = norm(x)
local t = {}
for i = 0, 31 do
local b = x % 2
t[i] = b
x = (x - b) / 2
end
return t
end
-- Convert bit table to number
local function frombits(t)
local x = 0
local p = 1
for i = 0, 31 do
if t[i] == 1 then
x = x + p
end
p = p * 2
end
return norm(x)
end
-- ===== Logical ops =====
function bit32.band(...)
local args = {...}
if #args == 0 then return 0xFFFFFFFF end
local bits = tobits(args[1])
for i = 2, #args do
local b = tobits(args[i])
for j = 0, 31 do
bits[j] = (bits[j] == 1 and b[j] == 1) and 1 or 0
end
end
return frombits(bits)
end
function bit32.bor(...)
local args = {...}
if #args == 0 then return 0 end
local bits = tobits(args[1])
for i = 2, #args do
local b = tobits(args[i])
for j = 0, 31 do
bits[j] = (bits[j] == 1 or b[j] == 1) and 1 or 0
end
end
return frombits(bits)
end
function bit32.bxor(...)
local args = {...}
if #args == 0 then return 0 end
local bits = tobits(args[1])
for i = 2, #args do
local b = tobits(args[i])
for j = 0, 31 do
bits[j] = (bits[j] ~= b[j]) and 1 or 0
end
end
return frombits(bits)
end
function bit32.bnot(x)
local bits = tobits(x)
for i = 0, 31 do
bits[i] = bits[i] == 1 and 0 or 1
end
return frombits(bits)
end
-- ===== Shifts =====
function bit32.lshift(x, n)
return norm(norm(x) * 2^n)
end
function bit32.rshift(x, n)
return math.floor(norm(x) / 2^n)
end
function bit32.arshift(x, n)
x = norm(x)
if x >= MOD31 then
return math.floor((x - MOD32) / 2^n)
else
return math.floor(x / 2^n)
end
end
-- ===== Rotates =====
function bit32.lrotate(x, n)
n = n % 32
x = norm(x)
local left = (x * 2^n) % MOD32
local right = math.floor(x / 2^(32 - n))
return norm(left + right)
end
function bit32.rrotate(x, n)
n = n % 32
x = norm(x)
local right = math.floor(x / 2^n)
local left = (x * 2^(32 - n)) % MOD32
return norm(left + right)
end
-- ===== Bit fields =====
function bit32.extract(x, field, width)
width = width or 1
return bit32.band(bit32.rshift(x, field), 2^width - 1)
end
function bit32.replace(x, v, field, width)
width = width or 1
local mask = bit32.lshift(2^width - 1, field)
x = bit32.band(x, bit32.bnot(mask))
return bit32.bor(x, bit32.lshift(v, field))
end
return bit32