web-dev-qa-db-ja.com

Luaでビット演算子XORを使用するにはどうすればよいですか?

Lua言語でビット演算子を実装するにはどうすればよいですか?
具体的には、XOR演算子/メソッドが必要です。

11
Trevor

Lua 5.2では、bit32ライブラリの関数を使用できます。

Lua 5.3では、ネイティブ ビット演算子 が存在するため、bit32ライブラリは廃止されました。

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

出力:

1
7
6
3
14
-8
18
Yu Hao

Lua 5.2では、bit32.bxor関数を使用できます。

11

床関数を3回参照しているため、ほとんどの操作で過剰な数のループを使用し(2 ^ 31未満の数では、31のループすべてが必要なわけではありません)、^演算子を使用しており、事実を利用していません。 aとbは、大きさが大きく異なる数値である可能性があるため、効率が大幅に低下します。関数もローカライズされておらず、必要以上に2つの除算演算を実行しています。私はこれを適度に速いように書いた。

一般的に、約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
Trey Reynolds

ビット単位のシフトを行うための効率的な方法が必要な場合は、少し前に それに関する記事 を書きました。テクニックをラップするいくつかの関数は次のとおりです。

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

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

OPから;質問からこの回答に移りました。


これは私がLuaでXORを実装した方法です:

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
0
George Stocker



これは非常に簡単です。 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

これが誰かを助けることを願っています。

0
Tonguç Endem