В направлении от string
до number
функция tonumber()
принимает необязательный второй аргумент, задающий базу для использования, которая может варьироваться от 2 до 36 с очевидным значением для цифрв базах больше 10.
В направлении числа к строке это можно сделать несколько эффективнее, чем ответ Николауса примерно так:
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()
былразработан, чтобы работать значительно лучше.
Остается без ответа вопрос о том, более эффективно ли помещать цифры в стек в таблице t
с помощью вызовов table.insert(t,1,digit)
или добавлять их кзавершите t[#t+1]=digit
, а затем вызовом string.reverse()
, чтобы расположить цифры в правильном порядке.Я оставлю тестирование студенту.Обратите внимание, что хотя код, который я вставил сюда, действительно работает и, кажется, получает правильные ответы, могут быть и другие возможности для его дальнейшей настройки.
Например, общий случай базы 10 отбирается и обрабатывается встроеннымtostring()
функция.Но подобные проверки могут быть выполнены для баз 8 и 16, которые имеют спецификаторы преобразования для string.format()
("%o"
и "%x"
, соответственно).
Кроме того, ни решение Николауса, ни мое не справляются с нецелыми числами особенно хорошо,Я подчеркиваю, что здесь принудительное приведение значения n
к целому числу с math.floor()
в начале.
Правильное преобразование общего значения с плавающей запятой в любое основание (даже основание 10) чревато тонкостями, которые яоставь читателю в качестве упражнения.