Bit Utils |
|
-- 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
If you need speed, the following is a lot faster (Arno Wagner <arno@wagner.name>):
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 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 local 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)