Lua:将整数打印为二进制

Posted

技术标签:

【中文标题】Lua:将整数打印为二进制【英文标题】:Lua: print integer as a binary 【发布时间】:2012-02-23 04:34:18 【问题描述】:

如何将整数表示为二进制?

所以我可以将7 打印为111

【问题讨论】:

看看here(我猜没有内置函数?) 有点过时了:) 【参考方案1】:

你写了一个函数来做这个。

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))

在 Lua 5.2 中,您已经拥有可以帮助您的按位函数 (bit32)


这是最重要的版本,可选的前导 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

【讨论】:

你的函数中有反转位,所以20 将返回00101,而不是10100 你没有说明你想要大端还是小端。该示例也没有泄露它,因为 111 是回文;)。无论如何,调整它很容易:只需使用 nBits=ceiling(select(2,math.frexp(num))) 并使用从 nBits 开始到 1 的 for 循环。 我的错,对不起,但是答案是正确和有用的,谢谢! 我在您的回答中添加了一个最重要的版本。我停止了对math.ceil() 的调用,因为据我所知, frexp 总是返回一个整数作为第二个值。有没有我遗漏的边缘案例? 确实不行,根据the manual on math.frexp,第二个返回值应该总是整数。感谢您的编辑!【参考方案2】:

有一种更快的方法可以利用 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。

如果你有 BitOp 库,它在 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,则结果将不正确。

【讨论】:

【参考方案3】:
function bits(num)
    local t=
    while num>0 do
        rest=num%2
        table.insert(t,1,rest)
        num=(num-rest)/2
    end return table.concat(t)
end

因为没有人愿意在 table.insert 有用的时候使用它

【讨论】:

其实使用 table.insert 会增加算法的复杂度从O(n)O(n^2)。做 jpjacobs 在他的评论中所说的,首先确定数字的长度,然后向后填充数组,效率更高。尤其是对于大数。唯一的变化是将while num>0 do 替换为for i=math.ceil(select(2,math.frexp(num))),1,-1 dot[#t+1] 替换为t[i]【参考方案4】:

这是一个受公认答案启发的函数,它使用正确的语法返回一个从右到左书写的位表。

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

【讨论】:

【参考方案5】:
function reverse(t)
  local nt =  -- new table
  local size = #t + 1
  for k,v in ipairs(t) do
    nt[size - k] = v
  end
  return nt
end

function tobits(num)
    local t=
    while num>0 do
        rest=num%2
        t[#t+1]=rest
        num=(num-rest)/2
    end
    t = reverse(t)
    return table.concat(t)
end
print(tobits(7))
# 111
print(tobits(33))
# 100001
print(tobits(20))
# 10100

【讨论】:

另一种方式是string.reverse(table.concat(t))【参考方案6】:
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

可能看起来更冗长,但它实际上比使用数学库函数的其他函数更快。适用于任何数字,无论是正数/负数/小数...

【讨论】:

【参考方案7】:
local function tobits(num, str) -- tail call
    str = str or "B"
    if num == 0 then return str end 
    return tobits( 
          num >> 1 , -- right shift
          ((num & 1)==1 and "1" or "0") .. str   )
end          

【讨论】:

【参考方案8】:

这可能不适用于没有 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)))

这个至少需要lua 5.2(因为代码需要bit32库)

【讨论】:

【参考方案9】:

和 Dave 一样,但填充了空位:

local function toBits(num, bits)
    -- returns a table of bits, least significant first.
    local t= -- will contain the bits
    bits = bits or 8
    while num>0 do
        rest=math.fmod(num,2)
        t[#t+1]=rest
        num=math.floor((num-rest)/2)
    end
    for i = #t+1, bits do -- fill empty bits with 0
        t[i] = 0
    end
    return t
end

for i = 0, 255 do
    local bits = toBits(i)
    print(table.concat(bits, '  '))
end

结果:

  0   0   0   0   0   0   0   0
  1   0   0   0   0   0   0   0
  0   1   0   0   0   0   0   0
  1   1   0   0   0   0   0   0
  0   0   1   0   0   0   0   0
  1   0   1   0   0   0   0   0
  ...
  0   1   1   1   1   1   1   1
  1   1   1   1   1   1   1   1

【讨论】:

以上是关于Lua:将整数打印为二进制的主要内容,如果未能解决你的问题,请参考以下文章

将整数向量打印为十进制数

lua能够用来写二进制数据吗?

如何将二进制整数转换为十六进制字符串?

如何在 Python 中使用 json.dumps() 将整数打印为十六进制字符串

如何以 0 作为十进制值打印整数?

Java将整数转换为十六进制整数