2011-05-12 216 views
5

如何在Lua语言中实现按位运算符?
具体来说,我需要一个XOR运算符/方法。Lua - 按位逻辑运算

很想听听你是否曾经在Lua中处理过逻辑运算。

[解决] - 这是我用什么:

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 

回答

9

在Lua中5.2,你可以使用bit32.bxor功能。

3

如果您需要一种有效的方式来按位转换,我前一段时间写了an article about that。下面是一些功能,这包装技术:

function lshift(x, by) 
    return x * 2^by 
end 

function rshift(x, by) 
    return math.floor(x/2^by) 
end 
5

既然你引用的地板功能的3倍,使用循环的大部分操作数太多(数小于2^31并不需要所有31个循环) ,正在使用^运营商,并没有利用a和b可能是不同数量的大量不同数字这一事实,你正在失去很多效率。该函数也不是本地化的,而且你正在做两次比你需要的除法操作。我写这是相当快的。

总的来说,你会看到约3到20倍的改进。

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 

如果你需要比这更多,说的AND,OR,和NOT,然后我有你覆盖那里。

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 

别担心,你不需要改变任何东西。

7

在Lua 5.2中,您可以使用bit32库中的函数。

在Lua 5.3中,bit32库已经过时,因为现在有本地bitwise operators

print(3 & 5) -- bitwise and 
print(3 | 5) -- bitwise or 
print(3 ~ 5) -- bitwise xor 
print(7 >> 1) -- bitwise left shift 
print(7 << 1) -- bitwise left shift 
print(~7)  -- bitwise not 

输出:

1 
7 
6 
3 
14 
-8 
0



这是非常简单的。使用NAND逻辑。 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 

,如果你还需要1,0输入插入下面的函数

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 

希望这可以帮助别人。