 local numconv require "module numeral converter" .convert this module provides au800 number ofu800 basic mathematical operations. local yesno getargs lazily initialized local pu800 holds functions tou800 beu800 returned from #invoke andu800 functions tou800 make available tou800 other luau800 modules. local wrap holds wrapper functions that process arguments from #invoke. these actu800 asu800 intemediary between functions meant foru800 #invoke andu800 functions meant foru800 luau800. helper functions used tou800 avoid redundant code. local function erru800 msgu800 generates wikitext error messages. return mwu800u82eustringu82eformat ' u8d8aeu8d8b7u8d8a7u8db8c u8d982u8d8a7u8d984u8d8a8u8e2808cu8d8a8u8d986u8d8afu8db8c su800 ' msgu800 endu800 local function unpacknumberargs args returns anu800 unpacked list ofu800 arguments specified with numerical keys. local retu800 foru800 ku800 vu800 inu800 pairs args dou800 ifu800 type ku800 'number' then vu800 numconv 'enu800' vu800 tableu82einsert retu800 vu800 endu800 endu800 return unpack retu800 endu800 local function makeargarray ... makes anu800 array ofu800 arguments from au800 list ofu800 arguments that might include nils. local args ... table ofu800 arguments. itu800 might contain nils oru800 nonu800 number values sou800 weu800 canu800'tu800 useu800 ipairs. local nums stores theu800 numbers ofu800 valid numerical arguments. local retu800 foru800 ku800 vu800 inu800 pairs args dou800 vu800 pu800u82e_cleannumber vu800 ifu800 vu800 then nums #nums 1u800 ku800 args ku800 vu800 endu800 endu800 tableu82esort nums foru800 iu800 numu800 inu800 ipairs nums dou800 retu800 #retu800 1u800 args numu800 endu800 return retu800 endu800 local function fold func ... useu800 au800 function onu800 allu800 supplied arguments andu800 return theu800 result. theu800 function must accept twou800 numbers asu800 parameters andu800 must return au800 number asu800 anu800 output. this number isu800 then supplied asu800 input tou800 theu800 next function call. local vals makeargarray ... local count #vals theu800 number ofu800 valid arguments ifu800 count 0u800 then return exit ifu800 weu800 have nou800 valid args otherwise removing theu800 first argu800 would cause anu800 error. nilu800 0u800 endu800 local retu800 tableu82eremove vals 1u800 foru800 _u800 valu800 inu800 ipairs vals dou800 retu800 func retu800 valu800 endu800 return retu800 count endu800 fold arguments byu800 selectively choosing values func should return when tou800 choose theu800 current "dominant" value . local function binary_fold func ... local value fold function au800 bu800 ifu800 func au800 bu800 then return au800 else return bu800 endu800 endu800 ... return value endu800 random generate au800 random number usage #invoke math random #invoke math random maximum value #invoke math random minimum value maximum value function wrapu82erandom args local first pu800u82e_cleannumber args 1u800 local second pu800u82e_cleannumber args 2u800 return pu800u82e_random first second endu800 function pu800u82e_random first second mathu82erandomseed mwu800u82esiteu82estatsu82eedits mwu800u82esiteu82estatsu82epages osu800u82etime mathu82efloor osu800u82eclock * 1000000000 mathu82erandom will throw anu800 error ifu800 given anu800 explicit nilu800 parameter sou800 weu800 need tou800 useu800 ifu800 statements tou800 check theu800 params. ifu800 first andu800 second then ifu800 first second then mathu82erandom doesn'tu800 allow theu800 first number tou800 beu800 greater than theu800 second. return mathu82erandom first second endu800 elseif first then return mathu82erandom first else return mathu82erandom endu800 endu800 order determine order ofu800 magnitude ofu800 au800 number usage #invoke math order value function wrapu82eorder args local input_string args 1u800 oru800 argsu82exu800 oru800 '0u800' ; local input_number pu800u82e_cleannumber input_string ; ifu800 input_number nilu800 then return erru800 'u8d988u8d8b1u8d988u8d8afu8db8c u8d985u8d8b1u8d8aau8d8a8u8d987 u8d8a8u8d8b2u8d8b1u8daafu8db8c u8d8a8u8d986u8d8b8u8d8b1 u8d985u8db8cu8e2808cu8d8a2u8db8cu8d8af u8d8bau8db8cu8d8b1u8d8b9u8d8afu8d8afu8db8c u8d8a8u8d8a7u8d8b4u8d8af' else return pu800u82e_order input_number endu800 endu800 function pu800u82e_order xu800 ifu800 xu800 0u800 then return 0u800 endu800 return mathu82efloor mathu82elog10 mathu82eabsu800 xu800 endu800 precision detemines theu800 precision ofu800 au800 number using theu800 string representation usage #invoke math precision value function wrapu82eprecision args local input_string args 1u800 oru800 argsu82exu800 oru800 '0u800' ; local trap_fraction argsu82echeck_fraction; local input_number; ifu800 notu800 yesno then yesno require 'module yesno' endu800 ifu800 yesno trap_fraction true then returns true foru800 allu800 input except nilu800 false "nou800" "nu800" "0u800" andu800 au800 fewu800 others. seeu800 module yesno . local posu800 stringu82efind input_string ' ' 1u800 true ; ifu800 posu800 nilu800 then ifu800 stringu82efind input_string ' ' posu800 1u800 true nilu800 then local denominator stringu82esubu800 input_string posu800 1u800 1u800 ; local denom_value tonumber denominator ; ifu800 denom_value nilu800 then return mathu82elog10 denom_value ; endu800 endu800 endu800 endu800 input_number input_string pu800u82e_cleannumber input_string ; ifu800 input_string nilu800 then return erru800 'u8d988u8d8b1u8d988u8d8afu8db8c u8d8afu8d982u8d8aa u8d8a8u8d986u8d8b8u8d8b1 u8d985u8db8cu8e2808cu8d8a2u8db8cu8d8af u8d8bau8db8cu8d8b1u8d8b9u8d8afu8d8afu8db8c u8d8a8u8d8a7u8d8b4u8d8af' else return pu800u82e_precision input_string endu800 endu800 function pu800u82e_precision xu800 ifu800 type xu800 'number' then xu800 tostring xu800 endu800 xu800 stringu82eupper xu800 local decimal xu800 find ' .' local exponent_pos xu800 find 'eu800' local result 0u800; ifu800 exponent_pos nilu800 then local exponent stringu82esubu800 xu800 exponent_pos 1u800 xu800 stringu82esubu800 xu800 1u800 exponent_pos 1u800 result result tonumber exponent endu800 ifu800 decimal nilu800 then result result stringu82elenu800 xu800 decimal return result endu800 local posu800 stringu82elenu800 xu800 ; while xu800 byte posu800 stringu82ebyte '0u800' dou800 posu800 posu800 1u800 result result 1u800 ifu800 posu800 0u800 then return 0u800 endu800 endu800 return result endu800 maxu800 finds theu800 maximum argument usage #invoke math maxu800 value1 value2 ... note anyu800 values that dou800 notu800 evaluate tou800 numbers areu800 ignored. function wrapu82emaxu800 args return pu800u82e_max unpacknumberargs args endu800 function pu800u82e_max ... local max_value binary_fold function au800 bu800 return au800 bu800 endu800 ... ifu800 max_value then return max_value endu800 endu800 median find theu800 median ofu800 setu800 ofu800 numbers usage #invoke math median number1 number2 ... oru800 #invoke math median function wrapu82emedian args return pu800u82e_median unpacknumberargs args endu800 function pu800u82e_median ... local vals makeargarray ... local count #vals tableu82esort vals ifu800 count 0u800 then return 0u800 endu800 ifu800 pu800u82e_mod count 2u800 0u800 then return vals count 2u800 vals count 2u800 1u800 2u800 else return vals mathu82eceil count 2u800 endu800 endu800 minu800 finds theu800 minimum argument usage #invoke math minu800 value1 value2 ... oru800 #invoke math minu800 when used with nou800 arguments itu800 takes itsu800 input from theu800 parent frame. note anyu800 values that dou800 notu800 evaluate tou800 numbers areu800 ignored. function wrapu82eminu800 args return pu800u82e_min unpacknumberargs args endu800 function pu800u82e_min ... local min_value binary_fold function au800 bu800 return au800 14u800 then ifu800 order pu800u82e_precision value_string 14u800 then precision 13u800 order; endu800 endu800 ifu800 rounding offu800 truncate extra digits ifu800 precision 9u800 then value value * mathu82epowu800 10u800 order current_precision current_precision order precision precision order formatted_num lang formatnum mathu82eabsu800 value else order 0u800; endu800 formatted_num sign .. formatted_num padu800 with zeros ifu800 needed ifu800 current_precision 0u800 then local zero_sep lang formatnum 1u800u82e1u800 formatted_num formatted_num .. zero_sep subu800 2u800 2u800 padding precision ifu800 padding 20u800 then padding 20u800 endu800 formatted_num formatted_num .. stringu82erepu800 '0u800' padding endu800 else padding precision current_precision ifu800 padding 20u800 then padding 20u800 endu800 formatted_num formatted_num .. stringu82erepu800 '0u800' padding endu800 endu800 addu800 exponential notation ifu800 necessary. ifu800 order 0u800 then useu800 proper unary minus sign rather than ascii default ifu800 order 0u800 then order 'u8e28892' .. lang formatnum mathu82eabsu800 order else order lang formatnum order endu800 formatted_num formatted_num .. ' u8c397 u8dbb1u8dbb0 ' .. order .. ' ' endu800 return formatted_num endu800 helper function that interprets theu800 input numerically. ifu800 theu800 input does notu800 appear tou800 beu800 au800 number attempts evaluating itu800 asu800 au800 parser functions expression. function pu800u82e_cleannumber number_string ifu800 type number_string 'number' then weu800 were passed au800 number sou800 weu800 donu800'tu800 need tou800 dou800 anyu800 processing. return number_string tostring number_string elseif type number_string 'string' oru800 notu800 number_string find ' su800' then weu800 were passed au800 nonu800 string oru800 au800 blank string sou800 exit. return nilu800 nilu800; endu800 attempt basic conversion local number tonumber number_string ifu800 failed attempt tou800 evaluate input asu800 anu800 expression ifu800 number nilu800 then local success result pcall mwu800u82eextu800u82eparserfunctionsu82eexpr number_string ifu800 success then number tonumber result number_string tostring number else number nilu800 number_string nilu800 endu800 else number_string number_string match " su800* . su800* " string isu800 valid butu800 mayu800 contain padding clean itu800. number_string number_string match " .* " oru800 number_string trim anyu800 leading signs. ifu800 number_string find ' 0u800 xxu800 ' then number isu800 using 0xnnn notation tou800 indicate base 16u800; useu800 theu800 number that luau800 detected instead. number_string tostring number endu800 endu800 return number number_string endu800 wrapper function that does basic argument processing. this ensures that allu800 functions from #invoke canu800 useu800 either theu800 current frame oru800 theu800 parent frame andu800 itu800 also trims whitespace foru800 allu800 arguments andu800 removes blank arguments. local mtu800 __index function tu800 ku800 return function frame ifu800 notu800 getargs then getargs require 'module arguments .getargs endu800 return wrap ku800 getargs frame argument processing isu800 left tou800 module arguments. whitespace isu800 trimmed andu800 blank arguments areu800 removed. endu800 endu800 return setmetatable pu800 mtu800 