How can I implement bitwise operators in Lua language?
Specifically, I need a XOR operator/method.
7 Answers
In Lua 5.2, you can use functions in bit32
library.
In Lua 5.3, bit32
library is obsoleted because there are now native bitwise operators.
print(3 & 5) -- bitwise and
print(3 | 5) -- bitwise or
print(3 ~ 5) -- bitwise xor
print(7 >> 1) -- bitwise right shift
print(7 << 1) -- bitwise left shift
print(~7) -- bitwise not
Output:
1
7
6
3
14
-8
Since you're referencing the floor function 3 times, using an excessive number of loops for most operations (numbers less than 2^31 don't need all 31 loops), are using the ^ operator, and aren't capitalizing on the fact that a and b might be wildly different numbers with different magnitudes, you're losing a lot of efficiency. The function also isn't localized, and you're doing two more division operations than you need to. I wrote this to be reasonably fast.
In general, you're going to see improvements of about 3 to 20 times.
local function BitXOR(a,b)--Bitwise xor
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
If you need more than this, say AND, OR, and NOT, then I've got you covered there, too.
local function BitOR(a,b)--Bitwise or
local p,c=1,0
while a+b>0 do
local ra,rb=a%2,b%2
if ra+rb>0 then c=c+p end
a,b,p=(a-ra)/2,(b-rb)/2,p*2
end
return c
end
local function BitNOT(n)
local p,c=1,0
while n>0 do
local r=n%2
if r<1 then c=c+p end
n,p=(n-r)/2,p*2
end
return c
end
local function BitAND(a,b)--Bitwise and
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
Don't worry, you won't need to change anything.
If you're needing an efficient way to do bitwise shifts, I wrote an article about that a while ago. Here's some functions which wrap the technique:
function lshift(x, by)
return x * 2 ^ by
end
function rshift(x, by)
return math.floor(x / 2 ^ by)
end
This is very simple. use NAND logic.
https://en.wikipedia.org/wiki/NAND_logic
function xor(a,b)
return not( not( a and not( a and b ) ) and not( b and not( a and b ) ) )
end
if you also need 1,0 inputs insert the following to the function
a = a==1 or a == true -- to accept nil, 1, 0, true or false
b = b==1 or b == true -- to accept nil, 1, 0, true or false
Hope this helps someone.