Binary Lua:将整数打印为二进制

Binary Lua:将整数打印为二进制,binary,lua,Binary,Lua,如何将整数表示为二进制 因此,我可以将7打印为111,您可以编写一个函数来实现这一点 num=7 function toBits(num) -- returns a table of bits, least significant first. local t={} -- will contain the bits while num>0 do rest=math.fmod(num,2) t[#t+1]=rest nu

如何将整数表示为二进制


因此,我可以将7打印为111,您可以编写一个函数来实现这一点

num=7
function toBits(num)
    -- returns a table of bits, least significant first.
    local t={} -- will contain the bits
    while num>0 do
        rest=math.fmod(num,2)
        t[#t+1]=rest
        num=(num-rest)/2
    end
    return t
end
bits=toBits(num)
print(table.concat(bits))
在Lua5.2中,您已经有了可以帮助您的按位函数

这是最重要的第一个版本,可选的前导0填充到指定的位数:

function toBits(num,bits)
    -- returns a table of bits, most significant first.
    bits = bits or math.max(1, select(2, math.frexp(num)))
    local t = {} -- will contain the bits        
    for b = bits, 1, -1 do
        t[b] = math.fmod(num, 2)
        num = math.floor((num - t[b]) / 2)
    end
    return t
end

由于没有人想使用table.insert,虽然它在这里很有用

这是一个受公认答案启发的函数,其语法正确,从右到左返回WRITEN格式的位表

num=255
bits=8
function toBits(num, bits)
    -- returns a table of bits
    local t={} -- will contain the bits
    for b=bits,1,-1 do
        rest=math.fmod(num,2)
        t[b]=rest
        num=(num-rest)/2
    end
    if num==0 then return t else return {'Not enough bits to represent this number'}end
end
bits=toBits(num, bits)
print(table.concat(bits))

>>11111111

有一种更快的方法可以利用string.format,它可以将数字转换为基数8。然后将基数8转换为二进制是很简单的

--create lookup table for octal to binary
oct2bin = {
    ['0'] = '000',
    ['1'] = '001',
    ['2'] = '010',
    ['3'] = '011',
    ['4'] = '100',
    ['5'] = '101',
    ['6'] = '110',
    ['7'] = '111'
}
function getOct2bin(a) return oct2bin[a] end
function convertBin(n)
    local s = string.format('%o', n)
    s = s:gsub('.', getOct2bin)
    return s
end
如果你想让它们都保持相同的尺寸,那就做吧

s = string.format('%.22o', n)
这就得到了66位。最后是两个额外的位,因为八进制以3位为一组工作,64不能被3整除。如果需要33位,请将其更改为11位

如果您拥有LuaJIT中默认可用的库,则可以执行以下操作:

function convertBin(n)
    local t = {}
    for i = 1, 32 do
        n = bit.rol(n, 1)
        table.insert(t, bit.band(n, 1))
    end
    return table.concat(t)
end

但请注意,这只对前32位起作用!如果您的数字大于2^32,则结果将不正确。

这可能不适用于没有bit32库的lua

    function toBinary(number, bits)
        local bin = {}
        bits = bits - 1
        while bits >= 0 do --As bit32.extract(1, 0) will return number 1 and bit32.extract(1, 1) will return number 0
                       --I do this in reverse order because binary should like that
            table.insert(bin, bit32.extract(number, bits))
            bits = bits - 1
        end
        return bin
    end
    --Expected result 00000011
    print(table.concat(toBinary(3, 8)))
local function tobinary( number )
  local str = ""
  if number == 0 then
      return 0
  elseif number < 0 then
      number = - number
      str = "-"
  end
  local power = 0
  while true do
      if 2^power > number then break end
      power = power + 1
  end
  local dot = true
  while true do
      power = power - 1
      if dot and power < 0 then
          str = str .. "."
          dot = false
      end
      if 2^power <= number then
          number = number - 2^power
          str = str .. "1"
      else
          str = str .. "0"
      end
      if number == 0 and power < 1 then break end
  end
  return str
end
这至少需要Lua5.2,因为代码需要bit32库

    function toBinary(number, bits)
        local bin = {}
        bits = bits - 1
        while bits >= 0 do --As bit32.extract(1, 0) will return number 1 and bit32.extract(1, 1) will return number 0
                       --I do this in reverse order because binary should like that
            table.insert(bin, bit32.extract(number, bits))
            bits = bits - 1
        end
        return bin
    end
    --Expected result 00000011
    print(table.concat(toBinary(3, 8)))
local function tobinary( number )
  local str = ""
  if number == 0 then
      return 0
  elseif number < 0 then
      number = - number
      str = "-"
  end
  local power = 0
  while true do
      if 2^power > number then break end
      power = power + 1
  end
  local dot = true
  while true do
      power = power - 1
      if dot and power < 0 then
          str = str .. "."
          dot = false
      end
      if 2^power <= number then
          number = number - 2^power
          str = str .. "1"
      else
          str = str .. "0"
      end
      if number == 0 and power < 1 then break end
  end
  return str
end
可能看起来更详细,但实际上它比使用数学库函数的其他函数更快。适用于任何数字,可以是正/负/分数…

本地函数tobitsnum,str-tail调用 str=str或B 如果num==0,则返回str end 返回托比 数值>>1,-右移位 num&1==1和1或0。。str 终止
看一看,我猜没有内置函数?它有点过时:函数中有反向位,因此20将返回00101,而不是10100。您没有说明是要使用大尾端还是小尾端。这个例子也没有透露,因为111是一个回文;。无论如何,调整它很容易:只需使用nBits=ceilingselect2,math.frexpnum并使用一个从nBits开始到1的for循环。我的错,对不起,尽管如此,答案是正确和有用的,谢谢!我在你的答案中添加了一个最重要的版本。我停止了对math.ceil的调用,因为据我所知,frexp总是为第二个值返回一个整数。是否有我遗漏的边缘情况?没有,实际上,根据,第二个返回值应该始终是整数。谢谢你的编辑!实际上,使用table.insert会将算法的复杂性从上增加到^2。按照jpjacobs在评论中所说的方法,首先确定数字的长度,然后向后填充数组,效率要高得多。特别是对于大量的人。唯一的更改是将i=math.ceilselect2、math.frexpnum、1、-1 do和t[t+1]的while num>0 do by替换为t[i]。另一种方法是string.reversetable.concatt