2010-08-24 67 views
6

我需要Lua的基本转换器函数。我需要从基数10转换为基数2,3,4,5,6,7,8,9,10,11 ... 36我怎么能这样?Lua base转换器

+1

基数2至36在文本中可用于编号方向,但不以其他方式显示有点奇怪。 – RBerteig 2010-08-24 08:54:02

+1

我正在计数的人:) Thue Morse-Sequence – Woland 2010-08-25 09:14:38

回答

13

stringnumber方向,功能tonumber()采用指定的基地使用,其可以大于10

在数为2至36具有明显的含义为位数基地字符串方向上的可选的第二个参数,这可以通过像这样的事情比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 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
    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性能,而table.concat()被设计为实现更好的性能。

有一个悬而未决的问题是它是否是更有效地与调用push数字堆栈上表中的ttable.insert(t,1,digit),或将其追加到与t[#t+1]=digit结束,随后调用string.reverse()放数字按正确的顺序排列。我将把基准留给学生。请注意,虽然我在这里粘贴的代码确实运行并似乎得到正确的答案,但还有其他机会可以进一步调整它。

例如,底座10的常见情况被剔除,并使用内置的tostring()功能进行处理。但是对于碱基8和碱基16可以进行类似的剔除,碱基8和16的转化说明符分别为string.format()(分别为"%o""%x")。

另外,尼古拉斯的解决方案和我的处理非整数都不是特别好。我强调在这里强制n的值为一个整数,开头为math.floor()

将一般浮点值正确地转换为任何基数(甚至是基数10)都充满了微妙之处,我将其作为练习留给读者。

3

您可以使用循环将整数转换为包含所需基数的字符串。对于低于10个碱基使用下面的代码,如果需要的基部比您需要添加MAPPS x%的碱的结果为一个字符的线的情况下(usign例如数组)

x = 1234 
r = "" 
base = 8 

while x > 0 do 
    r = "" .. (x % base) .. r 
    x = math.floor(x/base) 
end 
print(r); 
+1

tnx iem新的lua。 – Woland 2010-08-24 07:53:40

+1

注意:这不会处理负值或非整数值。负面很容易解决,你只需要在循环之前发现符号并使其成为正面。非整数更难。 – RBerteig 2010-08-24 08:53:19