<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.limswiki.org/index.php?action=history&amp;feed=atom&amp;title=Module%3AMath</id>
	<title>Module:Math - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.limswiki.org/index.php?action=history&amp;feed=atom&amp;title=Module%3AMath"/>
	<link rel="alternate" type="text/html" href="https://www.limswiki.org/index.php?title=Module:Math&amp;action=history"/>
	<updated>2026-04-04T15:37:52Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.36.1</generator>
	<entry>
		<id>https://www.limswiki.org/index.php?title=Module:Math&amp;diff=13160&amp;oldid=prev</id>
		<title>Shawndouglas: Created as needed.</title>
		<link rel="alternate" type="text/html" href="https://www.limswiki.org/index.php?title=Module:Math&amp;diff=13160&amp;oldid=prev"/>
		<updated>2013-10-30T23:37:55Z</updated>

		<summary type="html">&lt;p&gt;Created as needed.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[[&lt;br /&gt;
&lt;br /&gt;
This module provides a number of basic mathematical operations.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
local z = {}&lt;br /&gt;
&lt;br /&gt;
-- Generate random number&lt;br /&gt;
function z.random( frame )&lt;br /&gt;
    first = tonumber(frame.args[1]) -- if it doesn't exist it's NaN, if not a number it's nil&lt;br /&gt;
    second = tonumber(frame.args[2])&lt;br /&gt;
&lt;br /&gt;
    if first then -- if NaN or nil, will skip down to final return&lt;br /&gt;
        if first &amp;lt;= second then -- could match if both nil, but already checked that first is a number in last line&lt;br /&gt;
            return math.random(first, second)&lt;br /&gt;
        end&lt;br /&gt;
        return math.random(first)&lt;br /&gt;
    end   &lt;br /&gt;
    return math.random()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
order&lt;br /&gt;
&lt;br /&gt;
Determine order of magnitude of a number&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
    {{#invoke: Math | order | value }}&lt;br /&gt;
]]&lt;br /&gt;
function z.order(frame)&lt;br /&gt;
    local input_string = (frame.args[1] or frame.args.x or '0');&lt;br /&gt;
    local input_number;&lt;br /&gt;
    &lt;br /&gt;
    input_number = z._cleanNumber( frame, input_string );&lt;br /&gt;
    if input_number == nil then&lt;br /&gt;
        return '&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Formatting error: Order of magnitude input appears non-numeric&amp;lt;/strong&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
        return z._order( input_number )&lt;br /&gt;
    end    &lt;br /&gt;
end&lt;br /&gt;
function z._order(x)&lt;br /&gt;
    if x == 0 then return 0 end&lt;br /&gt;
    return math.floor(math.log10(math.abs(x)))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
precision&lt;br /&gt;
&lt;br /&gt;
Detemines the precision of a number using the string representation&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
    {{ #invoke: Math | precision | value }}&lt;br /&gt;
]]&lt;br /&gt;
function z.precision( frame )&lt;br /&gt;
    local input_string = (frame.args[1] or frame.args.x or '0');&lt;br /&gt;
    local trap_fraction = frame.args.check_fraction or false;&lt;br /&gt;
    local input_number;&lt;br /&gt;
    &lt;br /&gt;
    if type( trap_fraction ) == 'string' then&lt;br /&gt;
        trap_fraction = trap_fraction:lower();&lt;br /&gt;
        if trap_fraction == 'false' or trap_fraction == '0' or&lt;br /&gt;
                trap_fraction == 'no' or trap_fraction == '' then&lt;br /&gt;
            trap_fraction = false;&lt;br /&gt;
        else&lt;br /&gt;
            trap_fraction = true;&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    if trap_fraction then&lt;br /&gt;
        local pos = string.find( input_string, '/', 1, true );&lt;br /&gt;
        if pos ~= nil then&lt;br /&gt;
            if string.find( input_string, '/', pos + 1, true ) == nil then&lt;br /&gt;
                local denominator = string.sub( input_string, pos+1, -1 );&lt;br /&gt;
                local denom_value = tonumber( denominator );&lt;br /&gt;
                if denom_value ~= nil then&lt;br /&gt;
                    return math.log10(denom_value);&lt;br /&gt;
                end&lt;br /&gt;
            end                        &lt;br /&gt;
        end&lt;br /&gt;
    end    &lt;br /&gt;
    &lt;br /&gt;
    input_number, input_string = z._cleanNumber( frame, input_string );&lt;br /&gt;
    if input_string == nil then&lt;br /&gt;
        return '&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Formatting error: Precision input appears non-numeric&amp;lt;/strong&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
        return z._precision( input_string )&lt;br /&gt;
    end    &lt;br /&gt;
end&lt;br /&gt;
function z._precision( x )    &lt;br /&gt;
    x = string.upper( x )&lt;br /&gt;
&lt;br /&gt;
    local decimal = string.find( x, '.', 1, true )&lt;br /&gt;
    local exponent_pos = string.find( x, 'E', 1, true )&lt;br /&gt;
    local result = 0;&lt;br /&gt;
    &lt;br /&gt;
    if exponent_pos ~= nil then&lt;br /&gt;
        local exponent = string.sub( x, exponent_pos + 1 )&lt;br /&gt;
        x = string.sub( x, 1, exponent_pos - 1 )&lt;br /&gt;
        result = result - tonumber( exponent )&lt;br /&gt;
    end    &lt;br /&gt;
    &lt;br /&gt;
    if decimal ~= nil then&lt;br /&gt;
        result = result + string.len( x ) - decimal&lt;br /&gt;
        return result&lt;br /&gt;
    end&lt;br /&gt;
        &lt;br /&gt;
    local pos = string.len( x );&lt;br /&gt;
    while x:byte(pos) == string.byte('0') do&lt;br /&gt;
        pos = pos - 1&lt;br /&gt;
        result = result - 1&lt;br /&gt;
        if pos &amp;lt;= 0 then&lt;br /&gt;
            return 0&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
max&lt;br /&gt;
&lt;br /&gt;
Finds the maximum argument&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
    {{#invoke:Math| max | value1 | value2 | ... }}&lt;br /&gt;
OR&lt;br /&gt;
    {{#invoke:Math| max }}&lt;br /&gt;
&lt;br /&gt;
When used with no arguments, it takes its input from the parent&lt;br /&gt;
frame.  Note, any values that do not evaluate to numbers are ignored.&lt;br /&gt;
]]&lt;br /&gt;
function z.max( frame )&lt;br /&gt;
    local args = frame.args;&lt;br /&gt;
    &lt;br /&gt;
    if args[1] == nil then&lt;br /&gt;
        local parent = frame:getParent();&lt;br /&gt;
        args = parent.args;&lt;br /&gt;
    end&lt;br /&gt;
    local max_value = nil;&lt;br /&gt;
    &lt;br /&gt;
    local i = 1;&lt;br /&gt;
    while args[i] ~= nil do&lt;br /&gt;
        local val = z._cleanNumber( frame, args[i] );&lt;br /&gt;
        if val ~= nil then&lt;br /&gt;
            if max_value == nil or val &amp;gt; max_value then&lt;br /&gt;
                max_value = val;&lt;br /&gt;
            end&lt;br /&gt;
        end        &lt;br /&gt;
        i = i + 1;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    return max_value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
min &lt;br /&gt;
&lt;br /&gt;
Finds the minimum argument&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
    {{#invoke:Math| min | value1 | value2 | ... }}&lt;br /&gt;
OR&lt;br /&gt;
    {{#invoke:Math| min }}&lt;br /&gt;
&lt;br /&gt;
When used with no arguments, it takes its input from the parent&lt;br /&gt;
frame.  Note, any values that do not evaluate to numbers are ignored.&lt;br /&gt;
]]&lt;br /&gt;
function z.min( frame )&lt;br /&gt;
    local args = frame.args;&lt;br /&gt;
    &lt;br /&gt;
    if args[1] == nil then&lt;br /&gt;
        local parent = frame:getParent();&lt;br /&gt;
        args = parent.args;&lt;br /&gt;
    end&lt;br /&gt;
    local min_value = nil;&lt;br /&gt;
    &lt;br /&gt;
    local i = 1;&lt;br /&gt;
    while args[i] ~= nil do&lt;br /&gt;
        local val = z._cleanNumber( frame, args[i] );&lt;br /&gt;
        if val ~= nil then&lt;br /&gt;
            if min_value == nil or val &amp;lt; min_value then&lt;br /&gt;
                min_value = val;&lt;br /&gt;
            end&lt;br /&gt;
        end        &lt;br /&gt;
        i = i + 1;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    return min_value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
average &lt;br /&gt;
 &lt;br /&gt;
Finds the average&lt;br /&gt;
 &lt;br /&gt;
Usage:&lt;br /&gt;
    {{#invoke:Math| average | value1 | value2 | ... }}&lt;br /&gt;
OR&lt;br /&gt;
    {{#invoke:Math| average }}&lt;br /&gt;
 &lt;br /&gt;
When used with no arguments, it takes its input from the parent&lt;br /&gt;
frame.  Note, any values that do not evaluate to numbers are ignored.&lt;br /&gt;
]]&lt;br /&gt;
function z.average( frame )&lt;br /&gt;
    local args = frame.args;&lt;br /&gt;
    if args[1] == nil then&lt;br /&gt;
        local parent = frame:getParent();&lt;br /&gt;
        args = parent.args;&lt;br /&gt;
    end&lt;br /&gt;
    local sum = 0;&lt;br /&gt;
    local count = 0;&lt;br /&gt;
 &lt;br /&gt;
    local i = 1;&lt;br /&gt;
    while args[i] ~= nil do&lt;br /&gt;
        local val = z._cleanNumber( frame, args[i] );&lt;br /&gt;
        if val ~= nil then&lt;br /&gt;
            sum = sum + val&lt;br /&gt;
            count = count + 1&lt;br /&gt;
        end        &lt;br /&gt;
        i = i + 1;&lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
    return (count == 0 and 0 or sum/count)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
round&lt;br /&gt;
&lt;br /&gt;
Rounds a number to specified precision&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
    {{#invoke:Math | round | value | precision }}&lt;br /&gt;
    &lt;br /&gt;
--]]&lt;br /&gt;
function z.round(frame)&lt;br /&gt;
    local value, precision;&lt;br /&gt;
    &lt;br /&gt;
    value = z._cleanNumber( frame, frame.args[1] or frame.args.value or 0 );&lt;br /&gt;
    precision = z._cleanNumber( frame, frame.args[2] or frame.args.precision or 0 );&lt;br /&gt;
    &lt;br /&gt;
    if value == nil or precision == nil then&lt;br /&gt;
        return '&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Formatting error: Round input appears non-numeric&amp;lt;/strong&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
        return z._round( value, precision );&lt;br /&gt;
    end    &lt;br /&gt;
end&lt;br /&gt;
function z._round( value, precision )&lt;br /&gt;
    local rescale = math.pow( 10, precision );&lt;br /&gt;
    return math.floor( value * rescale + 0.5 ) / rescale;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
precision_format&lt;br /&gt;
&lt;br /&gt;
Rounds a number to the specified precision and formats according to rules &lt;br /&gt;
originally used for {{template:Rnd}}.  Output is a string.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
    {{#invoke: Math | precision_format | number | precision }}&lt;br /&gt;
]]&lt;br /&gt;
function z.precision_format( frame )&lt;br /&gt;
    -- For access to Mediawiki built-in formatter.&lt;br /&gt;
    local lang = mw.getContentLanguage();&lt;br /&gt;
    &lt;br /&gt;
    local value_string, value, precision;&lt;br /&gt;
    value, value_string = z._cleanNumber( frame, frame.args[1] or 0 );&lt;br /&gt;
    precision = z._cleanNumber( frame, frame.args[2] or 0 );&lt;br /&gt;
    &lt;br /&gt;
    -- Check for non-numeric input&lt;br /&gt;
    if value == nil or precision == nil then&lt;br /&gt;
        return '&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Formatting error: invalid input when rounding&amp;lt;/strong&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    local current_precision = z._precision( value );&lt;br /&gt;
&lt;br /&gt;
    local order = z._order( value );&lt;br /&gt;
    &lt;br /&gt;
    -- Due to round-off effects it is neccesary to limit the returned precision under&lt;br /&gt;
    -- some circumstances because the terminal digits will be inaccurately reported.&lt;br /&gt;
    if order + precision &amp;gt;= 14 then&lt;br /&gt;
        orig_precision = z._precision( value_string );&lt;br /&gt;
        if order + orig_precision &amp;gt;= 14 then&lt;br /&gt;
            precision = 13 - order;        &lt;br /&gt;
        end        &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- If rounding off, truncate extra digits&lt;br /&gt;
    if precision &amp;lt; current_precision then&lt;br /&gt;
        value = z._round( value, precision );&lt;br /&gt;
        current_precision = z._precision( value );&lt;br /&gt;
    end    &lt;br /&gt;
    &lt;br /&gt;
    local formatted_num = lang:formatNum( math.abs(value) );&lt;br /&gt;
    local sign;&lt;br /&gt;
    &lt;br /&gt;
    -- Use proper unary minus sign rather than ASCII default&lt;br /&gt;
    if value &amp;lt; 0 then&lt;br /&gt;
        sign = '−';&lt;br /&gt;
    else&lt;br /&gt;
        sign = '';&lt;br /&gt;
    end    &lt;br /&gt;
        &lt;br /&gt;
    -- Handle cases requiring scientific notation&lt;br /&gt;
    if string.find( formatted_num, 'E', 1, true ) ~= nil or math.abs(order) &amp;gt;= 9 then&lt;br /&gt;
        value = value * math.pow( 10, -order );&lt;br /&gt;
        current_precision = current_precision + order;&lt;br /&gt;
        precision = precision + order;&lt;br /&gt;
        formatted_num = lang:formatNum( math.abs(value) );&lt;br /&gt;
    else&lt;br /&gt;
        order = 0;        &lt;br /&gt;
    end&lt;br /&gt;
    formatted_num = sign .. formatted_num;&lt;br /&gt;
    &lt;br /&gt;
    -- Pad with zeros, if needed    &lt;br /&gt;
    if current_precision &amp;lt; precision then&lt;br /&gt;
        local padding;&lt;br /&gt;
        if current_precision &amp;lt;= 0 then&lt;br /&gt;
            if precision &amp;gt; 0 then&lt;br /&gt;
                local zero_sep = lang:formatNum( 1.1 );&lt;br /&gt;
                formatted_num = formatted_num .. zero_sep:sub(2,2);&lt;br /&gt;
&lt;br /&gt;
                padding = precision;&lt;br /&gt;
                if padding &amp;gt; 20 then&lt;br /&gt;
                    padding = 20;&lt;br /&gt;
                end&lt;br /&gt;
                &lt;br /&gt;
                formatted_num = formatted_num .. string.rep( '0', padding );&lt;br /&gt;
            end            &lt;br /&gt;
        else                   &lt;br /&gt;
            padding = precision - current_precision&lt;br /&gt;
            if padding &amp;gt; 20 then&lt;br /&gt;
                padding = 20;&lt;br /&gt;
            end&lt;br /&gt;
            formatted_num = formatted_num .. string.rep( '0', padding );&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Add exponential notation, if necessary.&lt;br /&gt;
    if order ~= 0 then&lt;br /&gt;
        -- Use proper unary minus sign rather than ASCII default&lt;br /&gt;
        if order &amp;lt; 0 then&lt;br /&gt;
            order = '−' .. lang:formatNum( math.abs(order) );&lt;br /&gt;
        else&lt;br /&gt;
            order = lang:formatNum( order );&lt;br /&gt;
        end    &lt;br /&gt;
        &lt;br /&gt;
        formatted_num = formatted_num .. '&amp;lt;span style=&amp;quot;margin:0 .15em 0 .25em&amp;quot;&amp;gt;×&amp;lt;/span&amp;gt;10&amp;lt;sup&amp;gt;' .. order .. '&amp;lt;/sup&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    return formatted_num;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper function that interprets the input numerically.  If the &lt;br /&gt;
input does not appear to be a number, attempts evaluating it as&lt;br /&gt;
a parser functions expression.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function z._cleanNumber( frame, number_string )&lt;br /&gt;
    if number_string == nil or number_string:len() == 0 then&lt;br /&gt;
        return nil, nil;&lt;br /&gt;
    end    &lt;br /&gt;
    &lt;br /&gt;
    -- Attempt basic conversion&lt;br /&gt;
    local number = tonumber( number_string )&lt;br /&gt;
    &lt;br /&gt;
    -- If failed, attempt to evaluate input as an expression&lt;br /&gt;
    if number == nil then        &lt;br /&gt;
        local attempt = frame:preprocess( '{{#expr: ' .. number_string .. '}}' );&lt;br /&gt;
        attempt = tonumber( attempt );&lt;br /&gt;
        if attempt ~= nil then&lt;br /&gt;
            number = attempt;&lt;br /&gt;
            number_string = tostring( number );&lt;br /&gt;
        else&lt;br /&gt;
            number = nil;&lt;br /&gt;
            number_string = nil;&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
    -- String is valid but may contain padding, clean it.&lt;br /&gt;
        number_string = number_string:match( &amp;quot;^%s*(.-)%s*$&amp;quot; );&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    return number, number_string;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return z&lt;/div&gt;</summary>
		<author><name>Shawndouglas</name></author>
	</entry>
</feed>