Lua:将整数以二进制形式打印

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

这样我就可以将 7 打印为 111

原文链接 https://stackoverflow.com/questions/9079853

点赞
stackoverflow用户513763
stackoverflow用户513763

你可以写一个函数来执行这个操作。

num=7
function toBits(num)
    -- 返回一个包含二进制位的表格,最低位在最前面。
    local t={} -- 将包含这些二进制位
    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)。


这里是最高位在最前面的版本,可以选择在前面补零来生成固定数量的位数:

function toBits(num,bits)
    -- 返回一个包含二进制位的表格,最高位在最前面。
    bits = bits or math.max(1, select(2, math.frexp(num)))
    local t = {} -- 将包含这些二进制位
    for b = bits, 1, -1 do
        t[b] = math.fmod(num, 2)
        num = math.floor((num - t[b]) / 2)
    end
    return t
end
2012-01-31 13:10:13
stackoverflow用户298624
stackoverflow用户298624
function reverse(t)
  local nt = {} -- 新表
  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

reverse 函数会将原表反转,返回一个新表。tobits 函数将十进制数转换成二进制位,使用了 reverse 函数。其中,# 表示获取表的长度,table.concat 用于将表中元素拼接成字符串。

2012-01-31 13:54:43
stackoverflow用户3434671
stackoverflow用户3434671
# 函数:bits(num)

该函数接受一个数字参数 num,返回一个二进制形式的字符串。

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

在该函数中,程序会将给定的数字转换成二进制数。具体实现方式是:状态变量 num 除以 2 得到商和余数,将余数插入临时表 t 的开头位置,再将 num 赋为商。重复以上步骤直到 num0。最后将表 t 中的元素拼接成一个字符串并返回。

因为该函数中用到了 table.insert 函数,而这个函数在一些情况下的效率非常低,所以有些人不愿使用 table.insert

2014-03-18 19:05:18
stackoverflow用户1919130
stackoverflow用户1919130

下面是一个受到接受答案启发的函数,具有正确的语法,返回从右向左编写的位表格。

num=255
bits=8
function toBits(num, bits)
    -- 返回位表格
    local t={} -- 将包含位
    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 {'没有足够的位来表示这个数字'}end
end
bits=toBits(num, bits)
print(table.concat(bits))

>>11111111
2014-11-02 18:36:04
stackoverflow用户2698948
stackoverflow用户2698948

有一个更快的方法可以利用 string.format 来完成,它可以将数字转换为八进制。然后将八进制转换为二进制非常简单。

-- 创建八进制到二进制的查找表
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位。这是在末尾多了两个额外的位,因为八进制的分组是三个一组的,而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,则结果将不正确。

2015-08-26 07:25:47
stackoverflow用户13447666
stackoverflow用户13447666
这段代码可能在没有 bit32 库的 lua 中无法运行。
function toBinary(number, bits)
    local bin = {}
    bits = bits - 1
    while bits >= 0 do --因为 bit32.extract(1, 0) 会返回值为 1,而 bit32.extract(1, 1) 会返回值为 0,所以我反着来做二进制
        table.insert(bin, bit32.extract(number, bits))
        bits = bits - 1
    end
    return bin
end
--预计结果为 00000011
print(table.concat(toBinary(3, 8)))

```

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

2020-05-14 09:44:56
stackoverflow用户10892084
stackoverflow用户10892084
-- 将数字转换为二进制字符串
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

可能看起来比较繁琐,但实际上比使用 math 库函数的其他函数更快。可以处理任何数字,无论是正数/负数/小数...

2020-12-25 00:19:30
stackoverflow用户14917287
stackoverflow用户14917287
本地函数 tobits(num, str) - 尾调用
    str = str or "B"
    如果 num == 0,则返回 str
    返回 tobits(
          num >> 1 , - 右移
          ((num & 1)==1 and "1" or "0") .. str   )
结束
2021-03-26 03:48:34
stackoverflow用户12968803
stackoverflow用户12968803
```lua
local function toBits(num, bits)
    -- 返回一个由比特位组成的表,从最低有效位开始
    local t={} -- 用来存放比特位
    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
        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
2021-12-21 16:53:19
stackoverflow用户9505653
stackoverflow用户9505653

这个函数使用查找表来打印从十六进制表示中提取的二进制数,基本上都是使用字符串操作。在 lua 5.1 中测试过。

local bin_lookup = {
    ["0"] = "0000",
    ["1"] = "0001",
    ["2"] = "0010",
    ["3"] = "0011",
    ["4"] = "0100",
    ["5"] = "0101",
    ["6"] = "0110",
    ["7"] = "0111",
    ["8"] = "1000",
    ["9"] = "1001",
    ["A"] = "1010",
    ["B"] = "1011",
    ["C"] = "1100",
    ["D"] = "1101",
    ["E"] = "1110",
    ["F"] = "1111"
}

local print_binary = function(value)
    local hs = string.format("%.2X", value) -- 将数字转换为十六进制
    local ln, str = hs:len(), "" -- 获取字符串长度
    for i = 1, ln do -- 循环遍历每个十六进制字符
        local index = hs:sub(i, i) -- 按顺序每个字符
        str = str .. bin_lookup[index] -- 查找表
        str = str .. " " -- 添加一个空格
    end
    return str
end

print(print_binary(45))
#0010 1101
print(print_binary(65000))
#1111 1101 1110 1000
2022-07-18 06:18:01