比较Lua中两个数字时的位差

时间:2013-12-26 18:13:01

标签: lua bit-manipulation octal hammingweight

我想比较两个数字来确定必须翻转的位数才能使它们相等。

例如,5和6需要2位翻转。

我可以手动执行此操作,但我想编写一个Lua函数来为我执行此操作,例如:

function (a,b)
  return hammingweight of a xor b
end

我只对将八进制与八进制(heheh)进行比较感兴趣,因此该函数将返回值0-3。是否有一种有效/优雅的方式来做这比使用表更好?

4 个答案:

答案 0 :(得分:3)

Lua 5.2中引入的bit32库使这个过程变得相当简单。

local bxor, band, rshift = bit32.bxor, bit32.band, bit32.rshift
local function ham(a, b)
  a = bxor(a, b)
  b = 0 -- Reuse b to count one bits.
  while a > 0 do
    b = b + band(a, 1)
    a = rshift(a, 1)
  end
  return b
end

print(ham(5,6)) -- 2

但是,如果您只是在一个足够小的范围内比较数字,例如07,那么您只需预先计算并保存结果。

local bxor = bit32.bxor
local hamcache = {[0] = 0, 1, 1, 2, 1, 2, 2, 3}
local function ham(a, b)
  return hamcache[bxor(a, b)]
end

答案 1 :(得分:2)

如果您通读以下链接中的函数,您将看到如果您有每个八进制数字的数组和二进制表示,则使用gsub函数将八进制表示中的每个数字替换为二进制数字。

http://lua-users.org/lists/lua-l/2002-10/msg00244.html

对于gsub,您可能需要查看http://lua-users.org/wiki/StringLibraryTutorial

一旦你有了这个,循环遍历每个角色,看看它们是否不同,并标记为chsnge那个位置。

答案 2 :(得分:1)

我认为最好的方法是:

  1. 检查最右边的位,即检查两个数字是偶数还是奇数。如果一个是,而另一个不是,这个位是不同的,所以将1加到加权总和上。
  2. 向右移1位(使用bit32.rshift(number, 1)或将除法的整数结果除以2)。
  3. 如果数字为0,则表示您已完成,否则请在1处重复。

答案 3 :(得分:1)

local function octal_ham(a, b)
  local x = bit32.bxor(a, b)
  return x - math.floor(x/2) - math.floor(x/4)
end