Module:NumberUtil
local p={} local lib_arg={} local lib_var={} local yesno = {} local lib_tempPar = {}
function p.foreachNumber(frame) local args, working_frame
if frame == mw.getCurrentFrame() then -- We're being called via #invoke. The args are passed through to the module -- from the template page, so use the args that were passed into the template. if lib_arg.getArgs == nil then lib_arg = require('Module:Arguments') end args = lib_arg.getArgs(frame, {parentFirst=true}) working_frame = frame else -- We're being called from another module or from the debug console, so assume -- the args are passed in directly. args = frame working_frame = mw.getCurrentFrame() if type(args) ~= type({}) then args = {frame} end end local input_article = args[1] or args['1'] or local input_calc = args[2] or args['2'] or '$1' local pattern = '#expr:' .. mw.ustring.gsub(input_calc,'%%(%d+)','%%%%%1') .. '}}' if mw.isSubsting() then pattern = 'safesubst:' .. pattern end pattern = '{{' .. pattern pattern = mw.ustring.gsub(pattern,'%$','(%%1)') local result = mw.ustring.gsub(input_article,'(%-?[%d%.]+)',pattern)
return working_frame:preprocess( result ) end
function p.forrangeNumber(frame) if lib_var._arg_process == nil then lib_var = require('Module:Var') end local args, working_frame = lib_var._arg_process(frame) local expr=args[4] or args['4'] or 'x' local var_name=args[5] or args['5'] or 'x' local var_str=args[6] or args['6'] or 'x' var_str = mw.ustring.gsub(var_str,"%%","%%%%"); expr = mw.ustring.gsub(expr,"%a+",function(str) if str==var_name then return "("..var_str..")" end end) expr = mw.ustring.gsub(expr,"[質质素][數数]","primeIndexAtModuleFactorization") local output_str=args[1] or args['1'] or '$1,' local start_n = tonumber(args[2] or args['2'] or args.min or '1')or 1 local end_n = tonumber(args[3] or args['3'] or args.max or '10')or 10 local math_lib = math local tonumber_func = tonumber
if args.template then if type(yesno) ~= type(tonumber) then yesno = require('Module:Yesno') end
if yesno(args.template or 'no') then return p.templateSequence(frame) end
end
if args.class then local comp_number; local num_class = mw.ustring.lower(args.class) if num_class == 'cmath' then if comp_number == nil then comp_number = require("Module:Complex Number") end math_lib = comp_number.cmath.init() tonumber_func = math_lib.toComplexNumber elseif num_class == 'qmath' then if comp_number == nil then comp_number = require("Module:Complex Number") end math_lib = comp_number.qmath.init() tonumber_func = math_lib.toQuaternionNumber else local calc_checkor = require("Module:Complex Number/Calculate") local module_name, math_lib_name = calc_checkor.checkModuleClass(args.class) xpcall(function() local load_module = require("Module:"..module_name) if load_module ~= nil then local load_math_lib = load_module[math_lib_name] if load_module ~= nil then local func_type = type(function()end) local my_math_lib = (type(load_math_lib.init) == func_type) and load_math_lib.init() or load_math_lib if type(my_math_lib.constructor) == func_type then math_lib = my_math_lib tonumber_func = my_math_lib.constructor end end end end,function()end) end end local series = false local raw_val = false
if args.series then if type(yesno) ~= type(tonumber) then yesno = require('Module:Yesno') end
series = yesno(args.series or 'no')
end if args.raw_value then if type(yesno) ~= type(tonumber) then yesno = require('Module:Yesno') end
raw_val = yesno(args.raw_value or 'no') end
if args.delnowiki then if type(yesno) ~= type(tonumber) then yesno = require('Module:Yesno') end
if yesno(args.delnowiki or 'no') then output_str = mw.text.unstripNoWiki( output_str ) end end if args.delmsgnw then
if type(yesno) ~= type(tonumber) then yesno = require('Module:Yesno') end if yesno(args.delmsgnw or 'no') then
output_str = mw.text.decode( output_str ) end end local input_arg = {useOtherModule="yes"} for ikey, ivalue in pairs(args) do if mw.ustring.find(ikey,"last") then input_arg[ikey] = ivalue end end local num_arr=mw.text.split(require("Module:FunctionGraph")._functionGraph({expr}, start_n,end_n,math.abs(start_n-end_n), nil, nil, input_arg,math_lib,tonumber_func).y1,',') local body="" if series==true then for i=1,#num_arr do local last = num_arr[i-1] num_arr[i] = tonumber_func(num_arr[i]) + tonumber_func(last or 0) end end for i=1,#num_arr do body = body .. mw.ustring.gsub(output_str,"(%$[+-]?[%d]*)",function(str) local tail = if str=="$+" or str=="$-" then tail = mw.ustring.sub(str,-1) end local check, num = mw.ustring.find(str,"[+-]?[%d]+") if check then num = tonumber(mw.ustring.sub(str, check, num) or ) or 1 else num = 1 end local idx = num+i-1 if num < 0 then idx = num+i end if num == 0 then return tostring(i+start_n-1) .. tail end local get_val if raw_val then if num < 0 and idx<1 then get_val = tostring(input_arg['last'..math.abs(num)]) else get_val = tostring(num_arr[idx]) end else if num < 0 and idx<1 then get_val = tonumber_func(input_arg['last'..math.abs(num)]) else get_val = tonumber_func(num_arr[idx]) end end
if mw.text.trim(tostring(get_val or )) ~= then return tostring(get_val) .. tail end return str end) end
if args.preprocess then if type(yesno) ~= type(tonumber) then yesno = require('Module:Yesno') end
if yesno(args.preprocess or 'no') then return working_frame:preprocess( body ) end end return body end
function p.templateSequence(frame) if lib_var._arg_process == nil then lib_var = require('Module:Var') end local args, working_frame = lib_var._arg_process(frame) local output_str=args[1] or args['1'] or '$1,' local start_n = tonumber(args[2] or args['2'] or args.min or '1')or 1 local end_n = tonumber(args[3] or args['3'] or args.max or '10')or 10 local expr = mw.ustring.format(" %s ", args[4] or args['4'] or '$')
if type(lib_tempPar._get_escape) ~= type(function()end) then lib_tempPar = require('Module:TemplateParameters') end
output_str = mw.text.unstripNoWiki( output_str ) expr = mw.text.unstripNoWiki(expr) if args.delmsgnw then
if type(yesno) ~= type(tonumber) then yesno = require('Module:Yesno') end if yesno(args.delmsgnw or 'no') then
output_str = mw.text.decode( output_str ) expr = mw.text.decode( expr ) end end
output_str = lib_tempPar._get_escape(output_str) expr = lib_tempPar._get_escape(expr) expr = mw.ustring.gsub(expr, "([^%$])%$([^%$])", function(prefix, suffix) return prefix.."\127MONEY\127"..suffix end) expr = mw.ustring.gsub(expr, "%$", "$$") expr = mw.ustring.gsub(expr, "\127MONEY\127", "$")
local body = local num_arr = {} for i=start_n, end_n do local result = expr result = mw.ustring.gsub(result, "([^%$])%$([^%$])", function(prefix, suffix) return prefix..i..suffix end) result = mw.ustring.gsub(result, "%$%$", "$") result = mw.ustring.sub(result, 2, -2) num_arr[#num_arr + 1] = result end for i=1,#num_arr do body = body .. mw.ustring.gsub(output_str,"(%$[+-]?[%d]*)",function(str) local tail = if str=="$+" or str=="$-" then tail = mw.ustring.sub(str,-1) end local check, num = mw.ustring.find(str,"[+-]?[%d]+") if check then num = tonumber(mw.ustring.sub(str, check, num) or ) or 1 else num = 1 end local idx = num+i-1 if num < 0 then idx = num+i end if num == 0 then return tostring(i+start_n-1) .. tail end local get_val if num < 0 and idx<1 then get_val = tostring(input_arg['last'..math.abs(num)]) else get_val = tostring(num_arr[idx]) end
if mw.text.trim(tostring(get_val or )) ~= then return tostring(get_val) .. tail end return str end) end return working_frame:preprocess( body ) end
function p.exp10link(frame) if lib_var._arg_process == nil then lib_var = require('Module:Var') end local args, working_frame = lib_var._arg_process(frame)
local input_number_str = args[1] or args['1'] or local digits = tonumber(input_number_str) if digits then local test_num = '1' if digits > 0 then for i=1,digits do test_num = test_num .. '0' end end if working_frame:preprocess( "Module:NumberUtil" ) == test_num then return "10" .. input_number_str .. "" end end return '10' .. input_number_str .. ''
end function p.MinusSignReplace(str) local input_str = str if type(str) == type({"table"}) then input_str = (str.args or {})[1] or str[1] or elseif type(str) ~= type("string") then input_str = tostring(str) end local body = mw.ustring.gsub(input_str,'%-','−') return body end
function p.fractionalGaps(str, _width, _suffix) local input_str = str local width = tonumber(_width) or 4 local suffix = _suffix or if type(str) == type({"table"}) then input_str = (str.args or {})[1] or str[1] or width = tonumber((str.args or {})[2] or str[2] or ) or 4 suffix = (str.args or {})[3] or str[3] or elseif type(str) ~= type("string") then input_str = tostring(str) end input_str = input_str .. '.' local point_pos = mw.ustring.find(input_str, "%.") local int_str, fractional_str = mw.ustring.sub(input_str, 1, point_pos-1), mw.ustring.sub(input_str, point_pos+1, -1) fractional_str = mw.ustring.gsub(fractional_str, "[^%d%a]", ) local fractional_length = mw.ustring.len(fractional_str) local body = int_str .. '.' local i = 1 while i <= fractional_length do local gap_part = mw.ustring.sub(fractional_str, i, i + width - 1) if gap_part == then break end if i <= 1 then body = body .. gap_part else body = body .. '' .. gap_part ..'' end i = i + width end return body .. (suffix ~= and ('' .. suffix ..'') or ) end
function p.numberListTemplate(frame) if lib_var._arg_process == nil then lib_var = require('Module:Var') end local args, working_frame = lib_var._arg_process(frame)
local input_number_str = args[1] or args['1'] or local failed = args.failed or local orginal_input_number_str = mw.text.trim(input_number_str)
input_number_str = mw.ustring.gsub(input_number_str,'[Ii][Nn][Ff]','inf') :gsub('∞','inf') :gsub('[Nn][Aa][Nn]','nan') if mw.ustring.find(input_number_str,'[无無][穷窮限]') then input_number_str = 'inf' end local function out_text(text) return mw.text.tag( "div", {style="text-align: center;"}, mw.text.tag( "small", {}, text)) end if mw.ustring.find(input_number_str,'除') then return out_text("除以零 除以一 除以二 除以三 >>") end if mw.ustring.find(input_number_str,'1/0') then return out_text("除以零 除以一 除以二 除以三 >>") end
input_number_str = mw.text.trim(input_number_str) local input_number = tonumber(input_number_str) if input_number then
local inf_msg = out_text("<< -∞ .... -0 0 .... ∞ >>")
if not not tostring(input_number):lower():find('inf') then return inf_msg end if not not tostring(input_number):lower():find('%-0') then return inf_msg end
if not not tostring(input_number):lower():find('nan') then return out_text("NaN (參見:浮點數、算術溢出)") end
local digits_log = math.floor(math.log10(math.abs(input_number)))+1 local is_zero = false if math.abs(input_number)<1e-8 then digits_log = 4 is_zero = true end local sign = ((input_number>0)and 1 or((input_number==0 or input_number==-0)and 0 or-1)) local int, frac = math.modf(math.abs(input_number)) local int10, frac10 = math.modf(math.abs(input_number) * 10)
local invocation = require('Module:Template invocation') local body =
if frac > 1e-8 then --小數模式 local get_frac = mw.ustring.gsub(input_number_str,'[%+%-]',) local _,frac_start = get_frac:find('%.') if frac_start then get_frac = get_frac:sub(frac_start+1,-1) else get_frac = tostring(frac):sub(3,-1) end local get_frac10 = '0' .. get_frac:sub(2,-1) local get_frac100 = '00' .. get_frac:sub(3,-1) if frac10 > 1e-8 then
body = body .. invocation.invocation("Numbers digits", { orginal_input_number_str, digit = '0.01', tail = ( sign < 0 and '-' or ) .. '0.'..get_frac100 })
end
body = body .. invocation.invocation("Numbers digits", { orginal_input_number_str, digit = '0.1'}) end for digits=1,digits_log do local current_unit = tonumber('1e'..(digits-1)) local current_mod = int % current_unit if current_mod == 0 then body = body .. invocation.invocation("Numbers digits", { orginal_input_number_str, digit = current_unit}) end end if is_zero then body = body .. inf_msg end return body
else return failed end
end function p.combineNumber(frame) local args, working_frame
if frame == mw.getCurrentFrame() then -- We're being called via #invoke. The args are passed through to the module -- from the template page, so use the args that were passed into the template. if lib_arg.getArgs == nil then lib_arg = require('Module:Arguments') end args = lib_arg.getArgs(frame, { parentFirst=true, trim = false,
removeBlanks = false
}) working_frame = frame else -- We're being called from another module or from the debug console, so assume -- the args are passed in directly. args = frame working_frame = mw.getCurrentFrame() if type(args) ~= type({}) then args = {frame} end end local input_article = args[1] or args['1'] or local spliter = {} input_spliter = mw.ustring.gsub(input_article, '(%d)', '%1%1%1') mw.ustring.gsub(input_spliter,'[%d%.]([^%d%.]+)[%d%.]',function(str) spliter[str] =(spliter[str] or 0)+1 return str end) local max_count = 0 local spliter_str = args[2] or args['2'] or ',' for value,v_count in pairs(spliter) do if v_count > max_count then max_count = v_count spliter_str = value end end if (args[2] or args['2']) ~= nil and (args[2] or args['2']) ~= then spliter_str = args[2] or args['2'] end if mw.text.trim(spliter_str or ) == then spliter_str = ' ' end local counting_sort = {} mw.ustring.gsub(input_article,'[%d%.]+',function(str) local n_first, n_last = mw.ustring.find(str,'%d+') if n_first then local num = tonumber(mw.ustring.sub(str, n_first, n_last)) if num then counting_sort[num] = counting_sort[num] or str end end return str end) local quick_sort = {} for value,v_count in pairs(counting_sort) do quick_sort[#quick_sort + 1] = {value,v_count} end table.sort( quick_sort, function(left,fight) return left[1] < fight[1] end )
local write_number = local output_arr = {} local trmp_str = for i=1,#quick_sort do if type(write_number) ~= type(0) then write_number = quick_sort[i][1] trmp_str = .. quick_sort[i][2] end if quick_sort[i][1] + 1 ~= (quick_sort[i+1]or{quick_sort[i][1]-1})[1] then if write_number ~= quick_sort[i][1] then trmp_str = trmp_str .. "-"..quick_sort[i][2] end output_arr[#output_arr + 1] = trmp_str write_number = end end
return table.concat( output_arr, spliter_str ) end return p