Pergi ke kandungan

Modul:Math

Daripada Wikipedia, ensiklopedia bebas.

Modul ini menyediakan sejumlah fungsi matematik. Fungsi-fungsi ini boleh digunakan dari #invoke atau dari modul Lua yang lain.

Gunakan dari modul Lua yang lain

[sunting sumber]

Untuk menggunakan modul dari halaman wiki biasa, tiada persediaan khas yang diperlukan. Sekiranya anda menggunakan modul dari modul Lua yang lain, pertama anda perlu memuatkannya, seperti ini:

localmm=require('Modul:Math')

(mmpembolehubah berdiri untukModulMath; anda boleh memilih sesuatu yang lebih deskriptif jika anda suka.)

Sebilangan besar fungsi dalam modul mempunyai versi untuk Lua dan versi untuk #invoke. Ia adalah mungkin untuk menggunakan fungsi-fungsi #invoke dari modul Lua lain, tetapi menggunakan fungsi Lua mempunyai kelebihan bahawa anda tidak perlu untuk mengaksesobjek bingkaiLua. Fungsi Lua didahului oleh_,sedangkan fungsi #invoke tidak.

{{#invoke:math|random}}
{{#invoke:math|random|max_value}}
{{#invoke:math|random|min_value|max_value}}
mm._random()
mm._random(max_value)
mm._random(min_value,max_value)

Menghasilkan nombor rawak.

  • Jika tiada argumen (alasan yang dikemukakan) yang ditentukan, jumlah yang dihasilkan adalah lebih besar daripada atau sama dengan 0 dan kurang daripada 1.
  • Jika satu argumen diberikan, nombor yang dihasilkan adalah bilangan bulat antara 1 dan argumen itu. Argumen mestilahinteger(angka bulat) positif.
  • Jika dua argumen disediakan, jumlah yang dihasilkan adalahintegerantara argumen yang pertama dan kedua. Kedua-dua argumen mestilahinteger,tetapi boleh menjadi negatif.

Fungsi ini tidak akan berfungsi dengan betul untuk nombor yang kurang daripada −232dan lebih besar daripada 232− 1. Sekiranya anda perlu menggunakan nombor di luar julat ini, disarankan agar anda menggunakanModul:Random.

{{#invoke:math|order|n}}
mm._order(n)

Menentukanperingkat magnituddaripada nombor.

ketepatan

[sunting sumber]
{{#invoke:math|precision|n}}
{{#invoke:math|precision|x=n}}
mm._precision(number_string)

Menentukan ketepatan nombor. Sebagai contoh, untuk "4" ia akan kembali ke "0", untuk "4.567" ia akan kembali ke "3", dan untuk "100" ia akan kembali ke "-2".

Fungsi ini cuba menguraikan perwakilan rentetan nombor, dan mengesan sama ada nombor itu menggunakannotasi E.Atas sebab ini, apabila dipanggil daripada Lua, nombor yang sangat besar atau nombor yang sangat tepat harus dimasukkan secara langsung sebagai rentetan untuk mendapatkan hasil yang tepat. Sekiranya mereka dimasukkan sebagai nombor, jurubahasa Lua akan mengubahnya menjadi notasi E dan fungsi ini akan mengembalikan ketepatan notasi E daripada nombor nombor asal. Ini tidak menjadi masalah apabila nombor dipanggil dari #invoke, kerana semua dimasukkan dari #invoke dalam format rentetan.

max (maksimum)

[sunting sumber]
{{#invoke:math|max|v1|v2|v3|...}}
mm._max(v1,v2,v3,...)

Mengembalikan nilai maksimum dari nilai yang ditentukan. Nilai yang tidak dapat ditukar menjadi nombor adalah diabaikan.

{{#invoke:math|median|v1|v2|v3|...}}
mm._median(v1,v2,v3,...)

Mengembalikanmediannilai dari nilai yang ditentukan. Nilai yang tidak dapat ditukar menjadi nombor adalah diabaikan.

min (minimum)

[sunting sumber]
{{#invoke:math|min|v1|v2|v3|...}}
mm._min(v1,v2,v3,...)

Mengembalikan nilai minimum dari nilai yang ditentukan. Nilai yang tidak dapat ditukar menjadi nombor adalah diabaikan.

{{#invoke:math|sum|v1|v2|v3|...}}
mm._sum(v1,v2,v3,...)

Mengembalikan jumlah nilai yang ditentukan. Nilai yang tidak dapat ditukar menjadi nombor adalah diabaikan.

{{#invoke:math|average|v1|v2|v3|...}}
mm._average(v1,v2,v3,...)

Mengembalikan purata nilai yang ditentukan. (Lebih tepatnya, nilai yang dikembalikan adalahpurata aritmetik.) Nilai yang tidak dapat ditukar menjadi nombor adalah diabaikan.

{{#invoke:math|round|value|precision}}
{{#invoke:math|round|value=value|precision=precision}}
mm._round(value,precision)

Putarannombor dengan ketepatan yang ditentukan.

Nota: Sehingga Oktober 2019, terdapat bug pada paparan beberapa nombor bulat. Semasa cuba membundarkan nombor yang bulat menjadi "n.0", seperti "1.02", hingga kesepuluh digit yang terdekat (i.e.|r=1), fungsi ini harus memaparkan "1.0", tetapi secara ia tidak disangka-sangka memaparkan "1". Sebagai ganti, gunakan parameter|precision_format=.

{{#invoke:math | log10 |x}}
mm._log10(x)

Mengembalikanlog10(x),Logaritmaxmenggunakan asas 10.

{{#invoke:math|mod|x|y}}
mm._mod(x,y)

Mendapatkanxmoduloy,atau selebihnya selepasxtelah dibahagi olehy.Ini adalah tepat untukintegersehingga 253;untuk integer yang lebih besar, operator modulo Lua boleh mengembalikan nilai yang salah. Fungsi ini berkait dengan masalah ini dengan mengembalikan0jika modulo yang diberikan oleh pengendali modulo Lua adalah kurang dari 0 atau lebih besar daripaday.

{{#invoke:math|gcd|v1|v2|...}}
mm._gcd(v1,v2,...)

Menemuifaktor sepunya terbesarnilai yang ditentukan. Nilai yang tidak dapat ditukar menjadi nombor adalah diabaikan.

ketepatan_format

[sunting sumber]
{{#invoke:math|precision_format|value_string|precision}}
mm._precision_format(value_string,precision)

Membundarkan nombor ke ketepatan dan format yang ditentukan mengikut peraturan yang awalnya digunakan untuk {{Rnd}}. Output adalah rentetan.

Ketepatan parameter hendaklah berupainteger.Nilai negatif dibenarkan. Bukan-integer memberikan hasil yang tidak dijangka

  • 1,234.567
  • 2: 1,234.57
  • −2: 1,200
  • 2.5: 1,234.5658476404
  • −2.5: 1,264.9110640674

cleanNumber

[sunting sumber]
localnumber,number_string=mm._cleanNumber(number_string)

Fungsi pembantu yang boleh dipanggil dari modul Lua lain, tetapi bukan dari #invoke. Ini mengambil rentetan atau nilai angka sebagai input, dan jika nilainya dapat ditukar menjadi angka, cleanNumber mengembalikan nombor dan rentetan nombor. Sekiranya nilainya tidak dapat ditukar menjadi nombor, cleanNumber kembali kepadanil, nil.

Lihat juga

[sunting sumber]

--[[

This module provides a number of basic mathematical operations.

]]

localyesno,getArgs-- lazily initialized

localp={}-- Holds functions to be returned from #invoke, and functions to make available to other Lua modules.
localwrap={}-- Holds wrapper functions that process arguments from #invoke. These act as intemediary between functions meant for #invoke and functions meant for Lua.

--[[
Helper functions used to avoid redundant code.
]]

localfunctionerr(msg)
-- Generates wikitext error messages.
returnmw.ustring.format('<strong class= "error" >Formatting error: %s</strong>',msg)
end

localfunctionunpackNumberArgs(args)
-- Returns an unpacked list of arguments specified with numerical keys.
localret={}
fork,vinpairs(args)do
iftype(k)=='number'then
table.insert(ret,v)
end
end
returnunpack(ret)
end

localfunctionmakeArgArray(...)
-- Makes an array of arguments from a list of arguments that might include nils.
localargs={...}-- Table of arguments. It might contain nils or non-number values, so we can't use ipairs.
localnums={}-- Stores the numbers of valid numerical arguments.
localret={}
fork,vinpairs(args)do
v=p._cleanNumber(v)
ifvthen
nums[#nums+1]=k
args[k]=v
end
end
table.sort(nums)
fori,numinipairs(nums)do
ret[#ret+1]=args[num]
end
returnret
end

localfunctionfold(func,...)
-- Use a function on all supplied arguments, and return the result. The function must accept two numbers as parameters,
-- and must return a number as an output. This number is then supplied as input to the next function call.
localvals=makeArgArray(...)
localcount=#vals-- The number of valid arguments
ifcount==0thenreturn
-- Exit if we have no valid args, otherwise removing the first arg would cause an error.
nil,0
end
localret=table.remove(vals,1)
for_,valinipairs(vals)do
ret=func(ret,val)
end
returnret,count
end

--[[
Fold arguments by selectively choosing values (func should return when to choose the current "dominant" value).
]]
localfunctionbinary_fold(func,...)
localvalue=fold((function(a,b)iffunc(a,b)thenreturnaelsereturnbendend),...)
returnvalue
end

--[[
random

Generate a random number

Usage:
{{#invoke: Math | random }}
{{#invoke: Math | random | maximum value }}
{{#invoke: Math | random | minimum value | maximum value }}
]]

functionwrap.random(args)
localfirst=p._cleanNumber(args[1])
localsecond=p._cleanNumber(args[2])
returnp._random(first,second)
end

functionp._random(first,second)
math.randomseed(mw.site.stats.edits+mw.site.stats.pages+os.time()+math.floor(os.clock()*1000000000))
-- math.random will throw an error if given an explicit nil parameter, so we need to use if statements to check the params.
iffirstandsecondthen
iffirst<=secondthen-- math.random doesn't allow the first number to be greater than the second.
returnmath.random(first,second)
end
elseiffirstthen
returnmath.random(first)
else
returnmath.random()
end
end

--[[
order

Determine order of magnitude of a number

Usage:
{{#invoke: Math | order | value }}
]]

functionwrap.order(args)
localinput_string=(args[1]orargs.xor'0');
localinput_number=p._cleanNumber(input_string);
ifinput_number==nilthen
returnerr('order of magnitude input appears non-numeric')
else
returnp._order(input_number)
end
end

functionp._order(x)
ifx==0thenreturn0end
returnmath.floor(math.log10(math.abs(x)))
end

--[[
precision

Detemines the precision of a number using the string representation

Usage:
{{ #invoke: Math | precision | value }}
]]

functionwrap.precision(args)
localinput_string=(args[1]orargs.xor'0');
localtrap_fraction=args.check_fraction;
localinput_number;

ifnotyesnothen
yesno=require('Module:Yesno')
end
ifyesno(trap_fraction,true)then-- Returns true for all input except nil, false, "no", "n", "0" and a few others. See [[Module:Yesno]].
localpos=string.find(input_string,'/',1,true);
ifpos~=nilthen
ifstring.find(input_string,'/',pos+1,true)==nilthen
localdenominator=string.sub(input_string,pos+1,-1);
localdenom_value=tonumber(denominator);
ifdenom_value~=nilthen
returnmath.log10(denom_value);
end
end
end
end

input_number,input_string=p._cleanNumber(input_string);
ifinput_string==nilthen
returnerr('precision input appears non-numeric')
else
returnp._precision(input_string)
end
end

functionp._precision(x)
iftype(x)=='number'then
x=tostring(x)
end
x=string.upper(x)

localdecimal=x:find('%.')
localexponent_pos=x:find('E')
localresult=0;

ifexponent_pos~=nilthen
localexponent=string.sub(x,exponent_pos+1)
x=string.sub(x,1,exponent_pos-1)
result=result-tonumber(exponent)
end

ifdecimal~=nilthen
result=result+string.len(x)-decimal
returnresult
end

localpos=string.len(x);
whilex:byte(pos)==string.byte('0')do
pos=pos-1
result=result-1
ifpos<=0then
return0
end
end

returnresult
end


--[[
max

Finds the maximum argument

Usage:
{{#invoke:Math| max | value1 | value2 |... }}

Note, any values that do not evaluate to numbers are ignored.
]]

functionwrap.max(args)
returnp._max(unpackNumberArgs(args))
end

functionp._max(...)
localmax_value=binary_fold((function(a,b)returna>bend),...)
ifmax_valuethen
returnmax_value
end
end

--[[
median

Find the median of set of numbers

Usage:
{{#invoke:Math | median | number1 | number2 |...}}
OR
{{#invoke:Math | median }}
]]

functionwrap.median(args)
returnp._median(unpackNumberArgs(args))
end

functionp._median(...)
localvals=makeArgArray(...)
localcount=#vals
table.sort(vals)

ifcount==0then
return0
end

ifp._mod(count,2)==0then
return(vals[count/2]+vals[count/2+1])/2
else
returnvals[math.ceil(count/2)]
end
end

--[[
min

Finds the minimum argument

Usage:
{{#invoke:Math| min | value1 | value2 |... }}
OR
{{#invoke:Math| min }}

When used with no arguments, it takes its input from the parent
frame. Note, any values that do not evaluate to numbers are ignored.
]]

functionwrap.min(args)
returnp._min(unpackNumberArgs(args))
end

functionp._min(...)
localmin_value=binary_fold((function(a,b)returna<bend),...)
ifmin_valuethen
returnmin_value
end
end

--[[
sum

Finds the sum

Usage:
{{#invoke:Math| sum | value1 | value2 |... }}
OR
{{#invoke:Math| sum }}

Note, any values that do not evaluate to numbers are ignored.
]]

functionwrap.sum(args)
returnp._sum(unpackNumberArgs(args))
end

functionp._sum(...)
localsums,count=fold((function(a,b)returna+bend),...)
ifnotsumsthen
return0
else
returnsums
end
end

--[[
average

Finds the average

Usage:
{{#invoke:Math| average | value1 | value2 |... }}
OR
{{#invoke:Math| average }}

Note, any values that do not evaluate to numbers are ignored.
]]

functionwrap.average(args)
returnp._average(unpackNumberArgs(args))
end

functionp._average(...)
localsum,count=fold((function(a,b)returna+bend),...)
ifnotsumthen
return0
else
returnsum/count
end
end

--[[
round

Rounds a number to specified precision

Usage:
{{#invoke:Math | round | value | precision }}

--]]

functionwrap.round(args)
localvalue=p._cleanNumber(args[1]orargs.valueor0)
localprecision=p._cleanNumber(args[2]orargs.precisionor0)
ifvalue==nilorprecision==nilthen
returnerr('round input appears non-numeric')
else
returnp._round(value,precision)
end
end

functionp._round(value,precision)
localrescale=math.pow(10,precisionor0);
returnmath.floor(value*rescale+0.5)/rescale;
end

--[[
log10

returns the log (base 10) of a number

Usage:
{{#invoke:Math | log10 | x }}
]]

functionwrap.log10(args)
returnmath.log10(args[1])
end

--[[
mod

Implements the modulo operator

Usage:
{{#invoke:Math | mod | x | y }}

--]]

functionwrap.mod(args)
localx=p._cleanNumber(args[1])
localy=p._cleanNumber(args[2])
ifnotxthen
returnerr('first argument to mod appears non-numeric')
elseifnotythen
returnerr('second argument to mod appears non-numeric')
else
returnp._mod(x,y)
end
end

functionp._mod(x,y)
localret=x%y
ifnot(0<=retandret<y)then
ret=0
end
returnret
end

--[[
gcd

Calculates the greatest common divisor of multiple numbers

Usage:
{{#invoke:Math | gcd | value 1 | value 2 | value 3 |... }}
--]]

functionwrap.gcd(args)
returnp._gcd(unpackNumberArgs(args))
end

functionp._gcd(...)
localfunctionfindGcd(a,b)
localr=b
localoldr=a
whiler~=0do
localquotient=math.floor(oldr/r)
oldr,r=r,oldr-quotient*r
end
ifoldr<0then
oldr=oldr*-1
end
returnoldr
end
localresult,count=fold(findGcd,...)
returnresult
end

--[[
precision_format

Rounds a number to the specified precision and formats according to rules
originally used for {{template:Rnd}}. Output is a string.

Usage:
{{#invoke: Math | precision_format | number | precision }}
]]

functionwrap.precision_format(args)
localvalue_string=args[1]or0
localprecision=args[2]or0
returnp._precision_format(value_string,precision)
end

functionp._precision_format(value_string,precision)
-- For access to Mediawiki built-in formatter.
locallang=mw.getContentLanguage();

localvalue
value,value_string=p._cleanNumber(value_string)
precision=p._cleanNumber(precision)

-- Check for non-numeric input
ifvalue==nilorprecision==nilthen
returnerr('invalid input when rounding')
end

localcurrent_precision=p._precision(value)
localorder=p._order(value)

-- Due to round-off effects it is neccesary to limit the returned precision under
-- some circumstances because the terminal digits will be inaccurately reported.
iforder+precision>=14then
iforder+p._precision(value_string)>=14then
precision=13-order;
end
end

-- If rounding off, truncate extra digits
ifprecision<current_precisionthen
value=p._round(value,precision)
current_precision=p._precision(value)
end

localformatted_num=lang:formatNum(math.abs(value))
localsign

-- Use proper unary minus sign rather than ASCII default
ifvalue<0then
sign='−'
else
sign=''
end

-- Handle cases requiring scientific notation
ifstring.find(formatted_num,'E',1,true)~=nilormath.abs(order)>=9then
value=value*math.pow(10,-order)
current_precision=current_precision+order
precision=precision+order
formatted_num=lang:formatNum(math.abs(value))
else
order=0;
end
formatted_num=sign..formatted_num

-- Pad with zeros, if needed
ifcurrent_precision<precisionthen
localpadding
ifcurrent_precision<=0then
ifprecision>0then
localzero_sep=lang:formatNum(1.1)
formatted_num=formatted_num..zero_sep:sub(2,2)

padding=precision
ifpadding>20then
padding=20
end

formatted_num=formatted_num..string.rep('0',padding)
end
else
padding=precision-current_precision
ifpadding>20then
padding=20
end
formatted_num=formatted_num..string.rep('0',padding)
end
end

-- Add exponential notation, if necessary.
iforder~=0then
-- Use proper unary minus sign rather than ASCII default
iforder<0then
order='−'..lang:formatNum(math.abs(order))
else
order=lang:formatNum(order)
end

formatted_num=formatted_num..'<span style= "margin:0.15em 0.25em" >×</span>10<sup>'..order..'</sup>'
end

returnformatted_num
end

--[[
divide

Implements the division operator

Usage:
{{#invoke:Math | divide | x | y | round= | precision= }}

--]]
functionwrap.divide(args)
localx=args[1]
localy=args[2]
localround=args.round
localprecision=args.precision
ifnotyesnothen
yesno=require('Module:Yesno')
end
returnp._divide(x,y,yesno(round),precision)
end

functionp._divide(x,y,round,precision)
ify==nilory==""then
returnerr("Empty divisor")
elseifnottonumber(y)then
iftype(y)=='string'andstring.sub(y,1,1)=='<'then
returny
else
returnerr("Not a number:"..y)
end
elseifx==nilorx==""then
returnerr("Empty dividend")
elseifnottonumber(x)then
iftype(x)=='string'andstring.sub(x,1,1)=='<'then
returnx
else
returnerr("Not a number:"..x)
end
else
localz=x/y
ifroundthen
returnp._round(z,0)
elseifprecisionthen
returnp._round(z,precision)
else
returnz
end
end
end

--[[
Helper function that interprets the input numerically. If the
input does not appear to be a number, attempts evaluating it as
a parser functions expression.
]]

functionp._cleanNumber(number_string)
iftype(number_string)=='number'then
-- We were passed a number, so we don't need to do any processing.
returnnumber_string,tostring(number_string)
elseiftype(number_string)~='string'ornotnumber_string:find('%S')then
-- We were passed a non-string or a blank string, so exit.
returnnil,nil;
end

-- Attempt basic conversion
localnumber=tonumber(number_string)

-- If failed, attempt to evaluate input as an expression
ifnumber==nilthen
localsuccess,result=pcall(mw.ext.ParserFunctions.expr,number_string)
ifsuccessthen
number=tonumber(result)
number_string=tostring(number)
else
number=nil
number_string=nil
end
else
number_string=number_string:match("^%s*(.-)%s*$")-- String is valid but may contain padding, clean it.
number_string=number_string:match("^%+(.*)$")ornumber_string-- Trim any leading + signs.
ifnumber_string:find('^%-?0[xX]')then
-- Number is using 0xnnn notation to indicate base 16; use the number that Lua detected instead.
number_string=tostring(number)
end
end

returnnumber,number_string
end

--[[
Wrapper function that does basic argument processing. This ensures that all functions from #invoke can use either the current
frame or the parent frame, and it also trims whitespace for all arguments and removes blank arguments.
]]

localmt={__index=function(t,k)
returnfunction(frame)
ifnotgetArgsthen
getArgs=require('Module:Arguments').getArgs
end
returnwrap[k](getArgs(frame))-- Argument processing is left to Module:Arguments. Whitespace is trimmed and blank arguments are removed.
end
end}

returnsetmetatable(p,mt)