Lua - побитовые логические операции - PullRequest
9 голосов
/ 12 мая 2011

Как я могу реализовать побитовые операторы на языке Lua?
В частности, мне нужен оператор / метод XOR.

Хотелось бы услышать, сталкивались ли вы когда-нибудь с логической операцией в 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

Ответы [ 5 ]

14 голосов
/ 16 января 2015

В 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
11 голосов
/ 16 мая 2011

В Lua 5.2 вы можете использовать функцию bit32.bxor.

7 голосов
/ 31 августа 2014

Поскольку вы ссылаетесь на функцию floor 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

Если вам нужно нечто большее, скажем, И, ИЛИ, и НЕ, тогда я вас тоже покрою.

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

Не волнуйтесь, вам не нужно ничего менять.

4 голосов
/ 17 мая 2011

Если вам нужен эффективный способ делать побитовые сдвиги, я написал статью об этом некоторое время назад.Вот некоторые функции, которые обертывают технику:

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

function rshift(x, by)
  return math.floor(x / 2 ^ by)
end
1 голос
/ 07 июня 2017



Это очень просто.использовать 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

Надеюсь, это кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...