模块:NumSysConvert

来自「荏苒之境」
Sicusa留言 | 贡献2025年8月11日 (一) 22:37的版本

此模块的文档可以在模块:NumSysConvert/doc创建

local num_sys_convert = {}

local DIGIT_MAP = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

local function decimal_to_base(input_num, target_base, digit_map, max_precision)
    if target_base < 2 or target_base > 36 then
        error("目标进制只支持2~36进制")
    elseif input_num == 0 then
    	return "0"
    end
    
    digit_map = digit_map or DIGIT_MAP
    max_precision = max_precision or 10
    
    local is_negative = input_num < 0
    input_num = math.abs(input_num)
    
    local integer_part = math.floor(input_num)
    local integer_result = ""
    local fractional_part = input_num - integer_part
    local fractional_result = ""
    
    if integer_part == 0 then
        integer_result = "0"
    else
        while integer_part > 0 do
            local remainder = integer_part % target_base
            integer_result = string.sub(
            	digit_map, remainder + 1, remainder + 1)..integer_result
            integer_part = math.floor(integer_part / target_base)
        end
    end
    
    if fractional_part > 0 then
        fractional_result = "."
        local precision_count = 0
        
        while fractional_part > 0 and precision_count < max_precision do
            fractional_part = fractional_part * target_base
            
            local current_digit = math.floor(fractional_part)
            fractional_result =
            	fractional_result
            	..string.sub(digit_map, current_digit + 1, current_digit + 1)
            	
            fractional_part = fractional_part - current_digit
            precision_count = precision_count + 1
        end
    end
    
    local final_result = integer_result..fractional_result
    if is_negative then
        final_result = "-"..final_result
    end
    return final_result
end

num_sys_convert.decimal_to_base = decimal_to_base

num_sys_convert.show = function(frame)
	local dec_str = string.gsub(frame.args.num, ",", "")
	local num = tonumber(dec_str)
	local base = tonumber(frame.args.base)
	local digit_map = frame.args.digit_map
	return decimal_to_base(num, base,
		digit_map ~= nil and digit_map ~= "" and digit_map or DIGIT_MAP)
end

return num_sys_convert