我需要Lua的基本转换器功能。我需要从基数10转换为基数2,3,4,5,6,7,8,9,10,11 ... 36我怎么能这样呢?
答案 0 :(得分:14)
在string
到number
方向,函数tonumber()
采用可选的第二个参数来指定要使用的基数,其范围可以是2到36,具有明显的数字含义在大于10的基数。
在数字到字符串的方向上,这可以比Nikolaus's answer更有效地完成这样的事情:
local floor,insert = math.floor, table.insert function basen(n,b) n = floor(n) if not b or b == 10 then return tostring(n) end local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" local t = {} local sign = "" if n < 0 then sign = "-" n = -n end repeat local d = (n % b) + 1 n = floor(n / b) insert(t, 1, digits:sub(d,d)) until n == 0 return sign .. table.concat(t,"") end
通过使用table.concat()
而不是重复调用字符串连接运算符..
,可以创建更少的垃圾字符串。虽然这对于这么小的字符串几乎没有什么实际意义,但是应该学习这个习惯用法,因为否则在使用连接运算符的循环中构建缓冲区实际上会倾向于O(n 2 )性能{{1}已被设计为做得更好。
有一个未解答的问题是,通过调用table.concat()
来推送表t
中的堆栈上的数字是否更有效,或者使用{{1}将它们追加到最后然后调用table.insert(t,1,digit)
以正确的顺序排列数字。我将基准测试留给学生。请注意,虽然我粘贴的代码确实运行并且似乎得到了正确的答案,但还有其他机会可以进一步调整它。
例如,基础10的常见情况被剔除并使用内置的t[#t+1]=digit
函数进行处理。但是对于基数8和16可以进行类似的剔除,它们分别具有string.reverse()
(tostring()
和string.format()
的转换说明符。)
此外,Nikolaus的解决方案和我的解决方案都不是特别好。我强调这是通过将值"%o"
强制为开头为"%x"
的整数。
正确地将一般浮点值转换为任何基数(甚至是基数10)都充满了微妙之处,我将其作为练习留给读者。
答案 1 :(得分:3)
您可以使用循环将整数转换为包含所需基数的字符串。对于10以下的基数,使用下面的代码,如果你需要一个大于你需要的基数来添加一行将x%base的结果映射到一个字符(例如,使用数组)
x = 1234
r = ""
base = 8
while x > 0 do
r = "" .. (x % base ) .. r
x = math.floor(x / base)
end
print( r );