# Bit Utils

These are bitwise operations implemented entirely in Lua.

### XOR

```-- 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```

It is also possible to do this without using the power function. The below implementation should be faster than the above in most cases. Though admittedly I have not verified this experimentally.

```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},
}
```

If speed is not your concern, the following could be shorter.

```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```

### Flags

```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)
```