Files
rime_wanxiang/lua/lib/bit.lua
2026-01-21 17:43:36 +08:00

69 lines
1.8 KiB
Lua

local bit_ok, bit_ = pcall(require, "bit") -- LuaJIT 内置 bit 库
local bit32_ok, bit32_ = pcall(require, "bit32") -- Lua 5.2 内置 bit32 库
---@alias fn_band fun(a: integer, b: integer): integer
---@alias fn_bxor fun(a: integer, b: integer): integer
---@type nil | { band: fn_band, bxor: fn_bxor }
local bit53_ = nil -- Lua 5.3 引入的原生位运算操作符
---@diagnostic disable-next-line: deprecated
local load_func = load or loadstring
if load_func then
---将新语法放入字符串中,避免在旧版 Lua 中导致语法错误
local bit53_func, bit53_err = load_func("return {" ..
"band = function(a, b) return a & b end," ..
"bxor = function(a, b) return a ~ b end," ..
"}")
if bit53_func and not bit53_err then
bit53_ = bit53_func()
end
end
local bit = {}
---@return integer
function bit.bxor(a, b)
if bit_ok then
return bit_.bxor(a, b)
elseif bit32_ok then
return bit32_.bxor(a, b)
elseif bit53_ then
return bit53_.bxor(a, b)
end
local p, c = 1, 0
while a > 0 and b > 0 do
local ra, rb = a % 2, b % 2
if ra ~= rb then c = c + p end
a, b, p = (a - ra) / 2, (b - rb) / 2, p * 2
end
if a < b then a = b end
while a > 0 do
local ra = a % 2
if ra > 0 then c = c + p end
a, p = (a - ra) / 2, p * 2
end
return c
end
---@return integer
function bit.band(a, b)
if bit_ok then
return bit_.band(a, b)
elseif bit32_ok then
return bit32_.band(a, b)
elseif bit53_ then
return bit53_.band(a, b)
end
local p, c = 1, 0
while a > 0 and b > 0 do
local ra, rb = a % 2, b % 2
if ra + rb > 1 then c = c + p end
a, b, p = (a - ra) / 2, (b - rb) / 2, p * 2
end
return c
end
return bit