Modul:Math: Unterschied zwischen den Versionen
Add support for rounding to specified precsion
(add max and min) |
(Add support for rounding to specified precsion) |
||
Zeile 15: | Zeile 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 | ||
function z._precision( x ) | function z._precision( x ) | ||
x = string.upper( x ) | x = string.upper( x ) | ||
Zeile 94: | Zeile 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 |