位运算工具 |
|
-- Bitwise XOR - thanks to Reuben Thomas local floor = math.floor function bxor (a,b) local r = 0 for i = 0, 31 do local x = a / 2 + b / 2 if x ~= floor (x) then r = r + 2^i end a = floor (a / 2) b = floor (b / 2) end return r end
如果您需要速度,以下方法要快得多(Arno Wagner <[email protected]>)
function bin_xor(x, y) local z = 0 for i = 0, 31 do if (x % 2 == 0) then -- x had a '0' in bit i if ( y % 2 == 1) then -- y had a '1' in bit i y = y - 1 z = z + 2 ^ i -- set bit i of z to '1' end else -- x had a '1' in bit i x = x - 1 if (y % 2 == 0) then -- y had a '0' in bit i z = z + 2 ^ i -- set bit i of z to '1' else y = y - 1 end end y = y / 2 x = x / 2 end return z end
也可以不使用幂函数来实现。以下实现方式在大多数情况下应该比上面更快。虽然我还没有通过实验验证这一点。
function xor(a,b) pow = 1 c = 0 while a > 0 or b > 0 do c = c + (XOR_l[(a % 2)+1][(b % 2)+1] * pow) a = math.floor(a/2) b = math.floor(b/2) pow = pow * 2 end return c end XOR_l = { {0,1}, {1,0}, }
如果速度不是您的主要考虑因素,以下方法可能更短。
local function nand(x,y,z) z=z or 2^16 if z<2 then return 1-x*y else return nand((x-x%z)/z,(y-y%z)/z,math.sqrt(z))*z+nand(x%z,y%z,math.sqrt(z)) end end math["not"]=function(y,z) return nand(nand(0,0,z),y,z) end math["and"]=function(x,y,z) return nand(math["not"](0,z),nand(x,y,z),z) end math["or"]=function(x,y,z) return nand(math["not"](x,z),math["not"](y,z),z) end math["xor"]=function(x,y,z) return math["and"](nand(x,y,z),math["or"](x,y,z),z) end
function testflag(set, flag) return set % (2*flag) >= flag end function setflag(set, flag) if set % (2*flag) >= flag then return set end return set + flag end function clrflag(set, flag) -- clear flag if set % (2*flag) >= flag then return set - flag end return set end -- Test suite b = { ['_0000'] = 0, ['_0001'] = 1, ['_0010'] = 2, ['_0011'] = 3, ['_1000'] = 8, ['_1010'] = 10, ['_1011'] = 11, } assert(not testflag(b._0000, b._0001)) assert(not testflag(b._0000, b._0010)) assert(not testflag(b._0010, b._0001)) assert( testflag(b._0010, b._0010)) assert(setflag(b._0000, b._0001) == b._0001) assert(setflag(b._0000, b._0010) == b._0010) assert(setflag(b._1010, b._0001) == b._1011) assert(setflag(b._1010, b._0010) == b._1010) assert(clrflag(b._0000, b._0001) == b._0000) assert(clrflag(b._0000, b._0010) == b._0000) assert(clrflag(b._1010, b._0001) == b._1010) assert(clrflag(b._1010, b._0010) == b._1000)