模組: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( "{{PAGENAME}}" ) == test_num then
return "'''10<sup>" .. input_number_str .. "</sup>'''"
end
end
return '[[1 E' .. input_number_str .. '|10<sup>' .. input_number_str .. '</sup>]]'
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 .. '<span style="margin-left: 0.25em">' .. gap_part ..'</span>'
end
i = i + width
end
return body .. (suffix ~= '' and ('<span style="margin-left: 0.25em">' .. suffix ..'</span>') 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