Documentation icon Τεκμηρίωση module[δημιουργία]
-- alternative to BaseConvert module. Can convert from any base between 1-36 to decimal, and from decimal to any base between 1-64. Does not support fractions, or negative numbers (abs'd to positive).
-- Gts@el wiki, Sep. 2017

local p = {}

local function tableMerge(t1, t2)
   for k,v in ipairs(t2) do
      table.insert(t1, v)
   end 
 
   return t1
end

local function convertbase(n, fromBase, toBase)
     
     -- usual case scenarios
     if n >= 0 and n <=9 and 
        fromBase == 10   and 
        toBase > 9       and 
        (toBase ~= 32 or toBase ~= 64) -- 32 and 64 base start with numerals instead of letters
        then return n 
     elseif fromBase < 37 and 
     	    toBase == 10 
     	    then return tonumber(n, fromBase) -- simply using internal Lua functionality (up to 36)
     end
     
     local digitPositions = {}
     while n > 0 do
     	 if toBase == 1 then
     	 	table.insert(digitPositions, 1)
     	 	n = n - 1
     	 else	
            table.insert(digitPositions, tonumber(n % toBase)) -- digit's position in the toBase numbering system
            n = math.floor(n / toBase)
         end
     end
     
     local digitValues = {}
     
     local numerals = {}
     for i = 0, 9 do table.insert(numerals, i) end
     
     local letters = {}
     for ascii = 65, 90 do table.insert(letters, string.char(ascii)) end -- uppercase letters
     for ascii = 97, 122 do table.insert(letters, string.char(ascii)) end -- lowercase letters 
     
     local symbols = {}
     table.insert(symbols, '+') -- 63rd digit
     table.insert(symbols, '-') -- 64th digit
     
     if toBase == 32 or toBase == 64 then
        tableMerge(digitValues, letters)
        tableMerge(digitValues, numerals)
     else
     	tableMerge(digitValues, numerals)
     	tableMerge(digitValues, letters)
     end
     
     tableMerge(digitValues, symbols)
     
     local result = ''
     for digit, value in pairs(digitPositions) do
     	result = tostring(digitValues[value+1]) .. result
     end
      
     return result
end

function p.convert(frame)
	local args = frame.args
	local number     = args.number    ~= nil and tonumber(args.number)    or 0 
	local fromBase   = args.fromBase  ~= nil and tonumber(args.fromBase)  or 10
	local toBase     = args.toBase    ~= nil and tonumber(args.toBase)    or 10
	local showRadix  = args.showRadix ~= nil and tonumber(args.showRadix) or 0
    
    if number == 0 then 
    	return '0<sub>' .. tostring(toBase)
    end
    
    if fromBase > 36 or toBase > 64 then
        result = 'Σφάλμα: οι αποδεκτές τιμές για βάση είναι 1 έως 64, και την βάση εκκίνησης από 1 έως 36'
    else
    	number   = math.abs(math.floor(number))
    	fromBase = math.abs(math.floor(fromBase))
    	toBase   = math.abs(math.floor(toBase))
    	
		result = convertbase(number, fromBase, toBase)
		
		if showRadix == 1 then
			result = tostring(result) .. '<sub>' .. tostring(toBase) .. '</sub>'
		end
	end
	
	return result
end

return p