Module:Radix: Difference between revisions

From Nguhcraft Wiki
Jump to navigation Jump to search
Astaryuu (talk | contribs)
No edit summary
Astaryuu (talk | contribs)
No edit summary
Line 3: Line 3:
r.decimal_to = function(frame)
r.decimal_to = function(frame)
-- Get arguments from call
-- Get arguments from call
format_output = format_output and format_output or true
local decimal = math.abs(tonumber(frame.args[1]))
local decimal = math.abs(tonumber(frame.args[1]))
Line 70: Line 71:
    -- run separator function on ret
    -- run separator function on ret
    if maxpower == 1 then
    if maxpower == 1 then
    ret = r.separator(ret, newradix)
    if format_output then ret = r.separator(ret, newradix) end
    if minpower < 1 then ret = ret .. "." end
    if minpower < 1 then ret = ret .. "." end
    end
    end

Revision as of 02:36, 5 July 2026

Documentation for this module may be created at Module:Radix/doc

local r = {}

r.decimal_to = function(frame)
	-- Get arguments from call
	format_output = format_output and format_output or true
	
	local decimal = math.abs(tonumber(frame.args[1]))
	local sign = decimal > 0 and "" or "-"
	-- If decimal is 1, return itself
	if decimal == 1 then
		return tostring(decimal)
	end
	-- Newradix is the radix to convert to
	local newradix = tonumber(frame.args[2])
	local characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	-- precision is the number of digits below 1 to use
	-- if decimal is less than 1/newradix ^ precision, return 0
	local precision = tonumber(frame.args[3]) or 0
	local minpower = newradix ^ (precision * -1)
	if decimal < minpower then
		return "0"
	end
	
	-- Weird radices
	-- If newradix is 1, just return decimal instead of erroring the formula
	if math.abs(newradix) == 1 then return tostring(decimal) end
	-- If newradix is negative it should use a different formulation; for now just do abs(newradix)
	if newradix < 0 then newradix = math.abs(newradix) end
	-- If newradix is nonintegral, character calculation is fucky, but probably fine
	
	-- final string to yeet everything into
	local ret = ""
	
	local maxpower = 1
	if decimal > 0 then
	    -- Get highest power of newradix less than decimal
	    while maxpower < decimal do
	    	maxpower = maxpower * newradix
	    end
	    maxpower = maxpower / newradix
	    
	    -- separate amount less than 1 and integer part (for separator function)
	    decimalpart = decimal - math.floor(decimal)
	    integralpart = math.floor(decimal)
	    
	    -- Double loop
	    -- Outer loop: While maxpower >= minpower, add result of second loop to ret
	    -- Inner loop: While decimal >= maxpower, subtract maxpower from decimal
	    while maxpower >= minpower do
	    	local digit = 1
	    	while decimal >= maxpower do
	    		decimal = decimal - maxpower
	    		digit = digit + 1
	    	end
	    	-- digit now contains number of maxpowers
	    	-- IF DIGIT = RADIX: add 1 to previous digit and make current digit "0"
	    	if digit == newradix+1 then
	    		if string.len(ret) > 0 then
	    			prevdigit = string.find(characters, string.sub(ret, -1, -1))[1]
	    			ret = string.sub(ret, 1, -2) .. string.sub(characters, prevdigit+1, prevdigit+1)
	    			digit = 1
	    		else
	    			ret = ret .. "1"
	    			digit = 1
	    		end
	    	end
	    	ret = ret .. string.sub(characters, digit, digit)
	    	
	    	-- when maxpower hits 1:
	    	-- append a . if maxpower went below 1 and there is more to print
	    	-- run separator function on ret
	    	if maxpower == 1 then
	    		if format_output then ret = r.separator(ret, newradix) end
	    		if minpower < 1 then ret = ret .. "." end
	    	end
	    	maxpower = maxpower / newradix
	    end
	    return sign .. ret
	else
		-- Decimal is 0, also return itself
		return tostring(decimal)
	end
end

-- Meant for internal use only, adds "," between every 3-4 digits depending on radix
r.separator = function(cs, radix)
	local dist = radix <= 6 and 3 or 4
	local separator = dist == 3 and "," or " "
	
	if string.len(cs) > dist then
		local pos = dist + 1
		while pos < string.len(cs) do
			cs = string.sub(cs, 1, (pos*-1)-1) .. separator .. string.sub(cs, pos*-1)
			pos = pos + dist + 2
		end
	end
	
	return cs
end

return r