Ir al contenido

Módulo:Math

De Biquipedia

La documentación para este módulo puede ser creada en Módulo:Math/doc

--[[

Iste modulo proporciona una serie d'operacions matematicas basicas.

]]
local z = {}

-- Chenera un numero aleatorio
function z.random(frame)
    local first = tonumber(frame.args[1])
    local second = tonumber(frame.args[2])
    local seed = tonumber(frame.args.seed)
    if seed then
        math.randomseed(seed * os.time())    -- inicialización pseudoaleatoria
    end
    if first and second then
        if first < second then
            return math.random(first,second)    -- entero entre [first,second]
        else
            return math.random(second,first)
        end
    elseif first then
        if first > 0 then
            return math.random(first)    -- entero entre [1,first]
        else
            return math.random(first,-1)
        end
    else
        return math.random()    -- numero real entre [0,1)
    end
end

--[[
order

Determina l'orden y a magnitut d'os numeros

Uso:
    {{#invoke: Math | order | <valor> }}
]]
function z.order(frame)
    local input_string = (frame.args[1] or frame.args.x or '0');
    local input_number;
    
    input_number = z._cleanNumber( frame, input_string );
    if input_number == nil then
        return '<strong class="error"><small>Error de formato: L\'orden de magnitut ha d\'estar numerico</small></strong>'
    else
        return z._order( input_number )
    end    
end
function z._order(x)
    if x == 0 then return 0 end
    return math.floor(math.log10(math.abs(x)))
end

--[[
precision

Detemina a precisión d'un numero usando a representación de cadena

Usar:
    {{ #invoke: Math | precision | <valor> }}
]]
function z.precision( frame )
    local input_string = (frame.args[1] or frame.args.x or '0');
    local trap_fraction = frame.args.check_fraction or false;
    local input_number;
    
    if type( trap_fraction ) == 'string' then
        trap_fraction = trap_fraction:lower();
        if trap_fraction == 'false' or trap_fraction == '0' or
                trap_fraction == 'no' or trap_fraction == '' then
            trap_fraction = false;
        else
            trap_fraction = true;
        end
    end
    
    if trap_fraction then
        local pos = string.find( input_string, '/', 1, true );
        if pos ~= nil then
            if string.find( input_string, '/', pos + 1, true ) == nil then
                local denominator = string.sub( input_string, pos+1, -1 );
                local denom_value = tonumber( denominator );
                if denom_value ~= nil then
                    return math.log10(denom_value);
                end
            end                        
        end
    end    
    
    input_number, input_string = z._cleanNumber( frame, input_string );
    if input_string == nil then
        return '<strong class="error"><small>Error de formato: A valor de precisión ha d\'estar numerico</small></strong>'
    else
        return z._precision( input_string )
    end    
end
function z._precision( x )    
    x = string.upper( x )

    local decimal = string.find( x, '.', 1, true )
    local exponent_pos = string.find( x, 'E', 1, true )
    local result = 0;
    
    if exponent_pos ~= nil then
        local exponent = string.sub( x, exponent_pos + 1 )
        x = string.sub( x, 1, exponent_pos - 1 )
        result = result - tonumber( exponent )
    end    
    
    if decimal ~= nil then
        result = result + string.len( x ) - decimal
        return result
    end
        
    local pos = string.len( x );
    while x:byte(pos) == string.byte('0') do
        pos = pos - 1
        result = result - 1
        if pos <= 0 then
            return 0
        end
    end
    
    return result
end

--[[
max

Busca l'argumento maximo

Uso:
    {{#invoke:Math| max | <valor1> | <valor2> | ... }}
o
    {{#invoke:Math| max }}

Quan s'emplega sin d'argumentos, prene a suya dentrada d'o marco superior. 
Pare cuenta que todas as valors que no s'evalúan como numeros son ignoradas.
]]
function z.max( frame )
    local args = frame.args;
    
    if args[1] == nil then
        local parent = frame:getParent();
        args = parent.args;
    end
    local max_value = nil;
    
    local i = 1;
    while args[i] ~= nil do
        local val = z._cleanNumber( frame, args[i] );
        if val ~= nil then
            if max_value == nil or val > max_value then
                max_value = val;
            end
        end        
        i = i + 1;
    end
  
    return max_value
end

--[[
min 

Busca l'argumento minimo

Uso:
    {{#invoke:Math| min | <valor1> | <valor2> | ... }}
o
    {{#invoke:Math| min }}

Quan s'emplega sin d'argumentos, prene a suya dentrada d'o marco superior. 
Pare cuenta que todas as valors que no s'evalúan como numeros son ignoradas
]]
function z.min( frame )
    local args = frame.args;
    
    if args[1] == nil then
        local parent = frame:getParent();
        args = parent.args;
    end
    local min_value = nil;
    
    local i = 1;
    while args[i] ~= nil do
        local val = z._cleanNumber( frame, args[i] );
        if val ~= nil then
            if min_value == nil or val < min_value then
                min_value = val;
            end
        end        
        i = i + 1;
    end
  
    return min_value
end

-- Función que cuenta o numero de parametros informaus
function z.cuenta( frame )
    local resultau = 0;
    local Argumentos = frame.args;
    
    if Argumentos[1] == nil then
        local parent = frame:getParent();
        Argumentos = parent.args;
    end    
    
    local i = 1;
    while Argumentos[i] ~= nil do
      if Argumentos[i] ~= '' then 	
    	resultau = resultau + 1
	  end
	  
	  i = i + 1;
    end
  
    return resultau
end

-- Función que suma os parametros
function z.suma( frame )
    local resultau = 0;
    local Argumentos = frame.args;
    
    if Argumentos[1] == nil then
        local parent = frame:getParent();
        Argumentos = parent.args;
    end    
    
    local i = 1;
    while Argumentos[i] ~= nil do
      if Argumentos[i] ~= '' then 	
    	resultau = resultau +  Argumentos[i]
	  end
	  
	  i = i + 1;
    end
  
    return resultau
end

--[[
round

Redondea un numero a la precisión especificada

Uso:
    {{#invoke:Math | round | <valor> | <precisión> }}
    
--]]
function z.round(frame)
    local value, precision;
    
    value = z._cleanNumber( frame, frame.args[1] or frame.args.value or 0 );
    precision = z._cleanNumber( frame, frame.args[2] or frame.args.precision or 0 );
    
    if value == nil or precision == nil then
        return '<strong class="error"><small>Error de formato: As valors han d\'estar numericas</small></strong>'
    else
        return z._round( value, precision );
    end    
end
function z._round( value, precision )
    local rescale = math.pow( 10, precision );
    return math.floor( value * rescale + 0.5 ) / rescale;
end

--[[
precision_format

Redondea un numero a la precisión especificada y le da formato d'alcuerdo con as normas
orichinalment emplegau pa {{Plantilla: Rnd}}. A salida ye una cadena.
Uso:
    {{#invoke: Math | precision_format | <número> | <precisión> }}
]]
function z.precision_format( frame )
    -- Pa acceder a Mediawiki incorporando formateador.
    local lang = mw.getContentLanguage();
    
    local value_string, value, precision;
    value, value_string = z._cleanNumber( frame, frame.args[1] or 0 );
    precision = z._cleanNumber( frame, frame.args[2] or 0 );
    
    -- Comprueba una dentrada no numerica
    if value == nil or precision == nil then
        return '<strong class="error"><small>Error de formato: Datos no validos para redondear</small></strong>'
    end
    
    local current_precision = z._precision( value );

    local order = z._order( value );
    
    -- Debiu a los efectos de redondeo, ye menester amugar a precisión tornada baixo
    -- bellas circunstancias, debiu a que sobre os dichitos terminals s'informó incorrectament.
    if order + precision >= 14 then
        orich_precision = z._precision( value_string );
        if order + orich_precision >= 14 then
            precision = 13 - order;        
        end        
    end

    -- Si o redondeo, trunca dichitos adicionals
    if precision < current_precision then
        value = z._round( value, precision );
        current_precision = z._precision( value );
    end    
    
    local formatted_num = lang:formatNum( math.abs(value) );
    local sign;
    
    -- Emplega o signo menos unario apropiau antis que no l'ASCII por defecto
    if value < 0 then
        sign = '−';
    else
        sign = '';
    end    
        
    -- Manullar os casos que requieren a notación scientifica
    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( math.abs(value) );
    else
        order = 0;        
    end
    formatted_num = sign .. formatted_num;
    
    -- Pad con zeros si cal    
    if current_precision < precision then
        local padding;
        if current_precision <= 0 then
            if precision > 0 then
                local zero_sep = lang:formatNum( 1.1 );
                formatted_num = formatted_num .. zero_sep:sub(2,2);

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

    -- Adhibe notación exponencial, si cal
    if order ~= 0 then
        -- Emplega o signo menos unario apropiau antis que no l'ASCII por defecto
        if order < 0 then
            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
    
    return formatted_num;
end

--[[
Función d'aduya que interpreta a dentrada numerica. 
Si a dentrada no ye un numero, lo intenta evaluar como
un «parser function» (Analizador sintactico).
]]

function z._cleanNumber( frame, number_string )
    if number_string == nil or number_string:len() == 0 then
        return nil, nil;
    end    
    
    -- Intenta a conversión basica
    local number = tonumber( number_string )
    
    -- Si falla, tracta d'evaluar a dentrada como expresión
    if number == nil then        
        local attempt = frame:preprocess( '{{#expr: ' .. number_string .. '}}' );
        attempt = tonumber( attempt );
        if attempt ~= nil then
            number = attempt;
            number_string = tostring( number );
        else
            number = nil;
            number_string = nil;
        end
    else
    -- A cadena ye valida pero puet contener repleno, limpiela.
        number_string = number_string:match( "^%s*(.-)%s*$" );
    end
    
    return number, number_string;
end

return z
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy