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 do
和t[#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:将整数打印为二进制的主要内容,如果未能解决你的问题,请参考以下文章