2011-05-12 115 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 

希望這可以幫助別人。