Module:Math: Difference between revisions

2,023 bytes added ,  11 years ago
Add support for rounding to specified precsion
m>Dragons flight
(add max and min)
m>Dragons flight
(Add support for rounding to specified precsion)
Line 15: Line 15:
end
end


-- Determine order of magnitude
function z.order(frame)
    return p._order(tonumber(frame.args[1] or frame.args.x or 0))
end
function z._order(x)
    if x == 0 then return 0 end
    return math.floor(math.log10(math.abs(x)))
end
-- Determines precision of a number using the string representation
function z.precision( frame )
function z.precision( frame )
     return z._precision( frame.args[1] or frame.args.x or '0' )
     return z._precision( frame.args[1] or frame.args.x or '0' )
end
end
-- Determines precision of a number using the string representation
function z._precision( x )
function z._precision( x )
     x = string.upper( x )
     x = string.upper( x )
Line 94: Line 102:
     return min_value
     return min_value
end
end
-- Rounds a number to the specified precision and formats according to rules
-- originally used for {{template:Rnd}}
function z.round( frame )
    -- For access to Mediawiki built-in formatter.
    local lang = mw.getContentLanguage();
   
    local value = tonumber( frame.args[1] or 0 );
    local precision = tonumber( frame.args[2] or 0 );
    local current_precision = p._precision( value );
   
    -- If rounding off, truncate extra digits
    if precision < current_precision then
        local rescale = math.pow( 10, precision );
        value = math.floor( value * rescale + 0.5 ) / rescale;
    end   
   
    local formatted_num = lang:formatNum( value );
    local order;
   
    -- Handle cases requiring scientific notation
    order = p._order( value );
    if string.find( formatted_num, 'E', 1, true ) ~= nil or math.abs(order) >= 9 then
        value = value * math.pow( 10, -order );
        current_precision = current_precision + order;
        precision = precision + order;
        formatted_num = lang:formatNum( value );
    else
        order = 0;       
    end
   
    -- Pad with zeros, if needed
    if current_precision < precision then
        if current_precision <= 0 then
            local zero_sep = lang:formatNum( 1.1 );
            formatted_num = formatted_num .. zero_sep:sub(2,2);
            formatted_num = formatted_num .. string.rep( '0', precision );
        else     
            formatted_num = formatted_num .. string.rep( '0', precision - current_precision );
        end
    end
    -- Add exponential notation, if necessary.
    if order ~= 0 then
        formatted_num = formatted_num .. '<span style="margin:0 .15em 0 .25em">×</span>10<sup>' .. lang:formatNum(order) .. '</sup>'
    end
   
    return formatted_num;
end
return z
return z
Anonymous user