Diferencia entre revisiones de «Módulo:Math»

De Hispanopedia
Sin resumen de edición
Supremo (discusión | contribs.)
m 18 revisiones importadas
 
(No se muestran 14 ediciones intermedias de 6 usuarios)
Línea 6: Línea 6:
local z = {}
local z = {}


-- Generar número aleatorio
-- Genera un número aleatorio
function z.random(frame)
function z.random(frame)
     local first = tonumber(frame.args[1])
     local first = tonumber(frame.args[1])
Línea 34: Línea 34:
order
order


Determinar  el orden y la magnitud de los números
Determina el orden y la magnitud de los números


Usar:
Uso:
     {{#invoke: Math | order | <valor> }}
     {{#invoke: Math | order | <valor> }}
]]
]]
Línea 58: Línea 58:
precision
precision


Deteminar la precisión de un número usando la representación de cadena
Detemina la precisión de un número usando la representación de cadena


Usar:
Usar:
Línea 167: Línea 167:
min  
min  


Buscar el argumento mínimo
Busca el argumento mínimo


Uso:
Uso:
Línea 198: Línea 198:
    
    
     return min_value
     return min_value
end
-- Función que cuenta el número de parámetros informados
function z.cuenta( frame )
    local resultado = 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
    resultado = resultado + 1
  end
 
  i = i + 1;
    end
 
    return resultado
end
-- Función que suma los parámetros
function z.suma( frame )
    local resultado = 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
    resultado = resultado +  Argumentos[i]
  end
 
  i = i + 1;
    end
 
    return resultado
end
end


Línea 205: Línea 249:
Redondea un número a la precisión especificada
Redondea un número a la precisión especificada


Usando:
Uso:
     {{#invoke:Math | round | <valor> | <precisión> }}
     {{#invoke:Math | round | <valor> | <precisión> }}
      
      
Línea 231: Línea 275:
Redondea un número a la precisión especificada y le da formato de acuerdo con las normas
Redondea un número a la precisión especificada y le da formato de acuerdo con las normas
originalmente utilizado para {{Plantilla: Rnd}}. La salida es una cadena.
originalmente utilizado para {{Plantilla: Rnd}}. La salida es una cadena.
Usage:
Uso:
     {{#invoke: Math | precision_format | <número> | <precisión> }}
     {{#invoke: Math | precision_format | <número> | <precisión> }}
]]
]]
function z.precision_format( frame )
function z.precision_format( frame )
     -- Para acceder a Mediawiki incorporado formateador.
     -- Para acceder a Mediawiki incorporando formateador.
     local lang = mw.getContentLanguage();
     local lang = mw.getContentLanguage();
      
      
Línea 252: Línea 296:
      
      
     -- Debido a los efectos de redondeo, es necesario limitar la precisión devuelta bajo
     -- Debido a los efectos de redondeo, es necesario limitar la precisión devuelta bajo
     -- algunas circunstancias debido a que sobre los dígitos terminales se informó incorrectamente.
     -- algunas circunstancias, debido a que sobre los dígitos terminales se informó incorrectamente.
     if order + precision >= 14 then
     if order + precision >= 14 then
         orig_precision = z._precision( value_string );
         orig_precision = z._precision( value_string );
Línea 311: Línea 355:
     end
     end


     -- Añadir notación exponencial, si es necesario
     -- Añade notación exponencial, si es necesario
     if order ~= 0 then
     if order ~= 0 then
         -- Utiliza el signo menos unario apropiado antes que el ASCII por defecto
         -- Utiliza el signo menos unario apropiado antes que el ASCII por defecto
Línea 329: Línea 373:
Función de ayuda que interpreta la entrada numérica.  
Función de ayuda que interpreta la entrada numérica.  
Si la entrada no es un número, lo intenta evaluar como
Si la entrada no es un número, lo intenta evaluar como
un parser function.
un «parser function» (Analizador sintáctico).
]]
]]


Línea 337: Línea 381:
     end     
     end     
      
      
     -- Intento de conversión básico
     -- Intenta la conversión básica
     local number = tonumber( number_string )
     local number = tonumber( number_string )
      
      
     -- Si falla, trate de evaluar entrada como expresión
     -- Si falla, trata de evaluar la entrada como expresión
     if number == nil then         
     if number == nil then         
         local attempt = frame:preprocess( '{{#expr: ' .. number_string .. '}}' );
         local attempt = frame:preprocess( '{{#expr: ' .. number_string .. '}}' );

Revisión actual - 13:33 18 oct 2023

Uso

Este módulo proporciona operaciones matemáticas básicas.

De momento, se utiliza solo la notación con punto decimal. Los parámetros de entrada deberían convertirse con {{formatnum:<num>|R}} y los valores devueltos se pueden formatear de nuevo con {{formatnum: <num>}}.

Funciones

random

Devuelve un número pseudoaleatorios. Sintaxis:

{{#Invoke:math|random}}

Sin ningún argumento, genera un número real en el rango [0,1) (con el 1 excluido), por ejemplo 0.27327761751287

{{#Invoke:math|random|<número>}}

Proporcionando un número entero, genera un número entero en el rango [1, número]. Si es negativo, el rango será [número, -1].

{{#Invoke:math|random|<primero>|<último>}}

Proporcionando dos números enteros, genera un número entero en el rango [primero, último].

Limitaciones: si se invoca más de una vez en la misma página entonces devolverá el mismo valor, aunque diferente cuando se refresque la página.

max

Encuentra el valor máximo de los argumentos. Sintaxis:

{{#Invoke:math|max|<valor 1>|<valor 2>|...}}
{{#Invoke:math|max}}

Cuando se usa sin argumentos, toma la entrada del marco superior. Cualquier valor numérico no válido es ignorado.

min

Encuentra el valor mínimo de los argumentos. Sintaxis:

{{#Invoke:math|min|<valor 1>|<valor 2>|...}}
{{#Invoke:math|min}}

Cuando se usa sin argumentos, toma la entrada del marco superior. Cualquier valor numérico no válido es ignorado.

cuenta

Cuenta el número de argumentos. Sintaxis:

{{#Invoke:math|cuenta|<valor 1>|<valor 2>|...}}
{{#Invoke:math|cuenta}}

Cuando se usa sin argumentos, toma la entrada del marco superior.

suma

suma los argumentos.

order

Determina el orden de magnitud de un número. Sintaxis:

{{#Invoke:math|order|<número>}}
{{#Invoke:math|order|x = <número>}}

Por ejemplo: 100 → 2, 0001 → -3

precision

Determina la precisión de un número. Sintaxis:

{{#Invoke:math|precision|<número>}}
{{#Invoke:math| precision| x = <número>}}

Es el inverso del orden de magnitud: indica el número de cifras decimales, incluidos ceros a la derecha, y una precisión negativa indica la potencia de 10 de la primera cifra significativa.

round

Redondea un número con una precisión determinada. Sintaxis:

{{#Invoke:math|round|<valor>|<precisión>}}
{{#Invoke:math|round|value = <valor>|precision = <precisión>}}

La precisión indica el número de cifras decimales. Una precisión negativa indica el múltiplo de la potencia de 10.

precision_format

Redondea un número con una precisión determinada y devuelve el valor en el formato numérico local o en notación científica cuando hace falta. Sintaxis:

{{#Invoke:math|precision_format|<número>|<precisión>}}

El número se puede expresar con la notación por ejemplo 4E9 y cuando el valor devuelto tiene un orden de magnitud de 9 o superior se expresa por ejemplo 4 × 10 9

_cleanNumber

Función auxiliar que evalúa si una entrada es numérica o si la puede convertir. Devuelve el valor numérico y el valor cadena. Puede ser útil en otros módulos.


--[[

Este módulo proporciona una serie de operaciones matemáticas básicas.

]]
local z = {}

-- Genera un número 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()    -- número real entre [0,1)
    end
end

--[[
order

Determina el orden y la magnitud de los números

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: El orden de magnitud debe ser numérico</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 la precisión de un número usando la 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: El valor de precisión ha de ser numérico</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 el argumento máximo

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

Cuando se utiliza sin argumentos, toma su entrada del marco superior. 
Tenga en cuenta que todos los valores que no se evalúan como números son ignorados.
]]
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 el argumento mínimo

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

Cuando se utiliza sin argumentos, toma su entrada del marco superior. 
Tenga en cuenta que todos los valores que no se evalúan como números son ignorados
]]
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 el número de parámetros informados
function z.cuenta( frame )
    local resultado = 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 	
    	resultado = resultado + 1
	  end
	  
	  i = i + 1;
    end
  
    return resultado
end

-- Función que suma los parámetros
function z.suma( frame )
    local resultado = 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 	
    	resultado = resultado +  Argumentos[i]
	  end
	  
	  i = i + 1;
    end
  
    return resultado
end

--[[
round

Redondea un número 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: Los valores han de ser numéricos</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 número a la precisión especificada y le da formato de acuerdo con las normas
originalmente utilizado para {{Plantilla: Rnd}}. La salida es una cadena.
Uso:
    {{#invoke: Math | precision_format | <número> | <precisión> }}
]]
function z.precision_format( frame )
    -- Para 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 entrada no numérica
    if value == nil or precision == nil then
        return '<strong class="error"><small>Error de formato: Datos no válidos para redondear</small></strong>'
    end
    
    local current_precision = z._precision( value );

    local order = z._order( value );
    
    -- Debido a los efectos de redondeo, es necesario limitar la precisión devuelta bajo
    -- algunas circunstancias, debido a que sobre los dígitos terminales se informó incorrectamente.
    if order + precision >= 14 then
        orig_precision = z._precision( value_string );
        if order + orig_precision >= 14 then
            precision = 13 - order;        
        end        
    end

    -- Si el redondeo, trunca dígitos adicionales
    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;
    
    -- Utiliza el signo menos unario apropiado antes que el ASCII por defecto
    if value < 0 then
        sign = '−';
    else
        sign = '';
    end    
        
    -- Manejar los casos que requieren la notación científica
    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 ceros si es necesario    
    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

    -- Añade notación exponencial, si es necesario
    if order ~= 0 then
        -- Utiliza el signo menos unario apropiado antes que el 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 de ayuda que interpreta la entrada numérica. 
Si la entrada no es un número, lo intenta evaluar como
un «parser function» (Analizador sintáctico).
]]

function z._cleanNumber( frame, number_string )
    if number_string == nil or number_string:len() == 0 then
        return nil, nil;
    end    
    
    -- Intenta la conversión básica
    local number = tonumber( number_string )
    
    -- Si falla, trata de evaluar la entrada 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
    -- La cadena es válida pero puede contener relleno, límpiela.
        number_string = number_string:match( "^%s*(.-)%s*$" );
    end
    
    return number, number_string;
end

return z