Lua基础转换器

我需要一个用于 Lua 的进制转换函数。我需要将数字从十进制转换为二进制、三进制、四进制、五进制、六进制、七进制、八进制、九进制、十进制、十一进制......直到三十六进制。我该如何做到这一点?

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

点赞
stackoverflow用户276076
stackoverflow用户276076

你可以使用循环将一个整数转换为包含所需基数的字符串。对于小于10的基数,使用以下代码。如果需要大于该值的基数,则需要添加一行将x % base的结果映射到字符的代码(例如使用数组)。

x = 1234
r = ""
base = 8

while x > 0 do
    r = "" ..  (x % base ) .. r
    x = math.floor(x / base)
end
print( r );
2010-08-24 07:47:33
stackoverflow用户68204
stackoverflow用户68204

stringnumber 的转换方向中,函数 tonumber() 接受一个可选的第二个参数,指定要使用的进制范围是从 2 到 36,对于大于 10 的进制,数字的含义也是显而易见的。

在数字到字符串的转换方向中,可以通过以下方式比 Nikolaus 的答案 更有效率地完成:


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) 的性能,而 table.concat() 设计得更好。

是否通过使用 table.insert(t,1,digit) 调用将数字推入表 t 中的堆栈,还是将它们附加到末尾并调用 string.reverse() 以使数字顺序正确,这个问题尚未解答。我将把基准测试留给学生们。请注意,虽然我在此贴的代码确实可以运行,并且似乎能得到正确的答案,但是可能还有其他调优的机会。

例如,可以使用内置的 tostring() 函数将通用情况下的十进制基数 10 筛选出来并处理掉。但是类似的筛选也可以用于具有 string.format() 的转换说明符的 8 和 16 进制基数(分别为 "%o""%x")。

此外,无论是 Nikolaus 的解决方案还是我的解决方案都不能很好地处理非整数。我在这里强调一下,通过在开头使用 math.floor() 将值 n 强制转换为整数。

将通用浮点值正确地转换为任何基数(甚至是基数 10)都有很多微妙之处,这些微妙之处留给读者作为练习。

2010-08-24 08:48:17