Lua:将整数以二进制形式打印
如何将整数表示为二进制?
这样我就可以将 7
打印为 111
。
原文链接 https://stackoverflow.com/questions/9079853
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
用于将表中元素拼接成字符串。
# 函数: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
赋为商。重复以上步骤直到 num
为 0
。最后将表 t
中的元素拼接成一个字符串并返回。
因为该函数中用到了 table.insert
函数,而这个函数在一些情况下的效率非常低,所以有些人不愿使用 table.insert
。
下面是一个受到接受答案启发的函数,具有正确的语法,返回从右向左编写的位表格。
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
有一个更快的方法可以利用 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,则结果将不正确。
这段代码可能在没有 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 库)。
-- 将数字转换为二进制字符串
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 库函数的其他函数更快。可以处理任何数字,无论是正数/负数/小数...
本地函数 tobits(num, str) - 尾调用
str = str or "B"
如果 num == 0,则返回 str
返回 tobits(
num >> 1 , - 右移
((num & 1)==1 and "1" or "0") .. str )
结束
```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
这个函数使用查找表来打印从十六进制表示中提取的二进制数,基本上都是使用字符串操作。在 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
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
你可以写一个函数来执行这个操作。
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