Diferencia entre revisiones de «Módulo:Math»

De Hispanopedia
Página creada con «--Este módulo proporciona una serie de operaciones matemáticas básicas. local z = {} -- Generar número aleatorio function z.random(frame) local first = ton...»
 
Sin resumen de edición
Línea 12: Línea 12:
     local seed = tonumber(frame.args.seed)
     local seed = tonumber(frame.args.seed)
     if seed then
     if seed then
         math.randomseed(seed * os.time())    -- inicialització pseudoaleatòria
         math.randomseed(seed * os.time())    -- inicialización pseudoaleatoria
     end
     end
     if first and second then
     if first and second then
         if first < second then
         if first < second then
             return math.random(first,second)    -- enter entre [first,second]
             return math.random(first,second)    -- entero entre [first,second]
         else
         else
             return math.random(second,first)
             return math.random(second,first)
Línea 138: Línea 138:
     {{#invoke:Math| max }}
     {{#invoke:Math| max }}


Cuando se utiliza sin argumentos, toma su entrada del frame Parent.  
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.
Tenga en cuenta que todos los valores que no se evalúan como números son ignorados.
]]
]]
Línea 174: Línea 174:
     {{#invoke:Math| min }}
     {{#invoke:Math| min }}


Cuando se utiliza sin argumentos, toma su entrada del frame parent
Cuando se utiliza sin argumentos, toma su entrada del marco superior.  
marco. Tenga en cuenta que todos los valores que no se evalúan como números son ignorados
Tenga en cuenta que todos los valores que no se evalúan como números son ignorados
]]
]]
function z.min( frame )
function z.min( frame )
Línea 251: Línea 251:
     local order = z._order( value );
     local order = z._order( value );
      
      
     -- Due to round-off effects it is neccesary to limit the returned precision under
     -- Debido a los efectos de redondeo, es necesario limitar la precisión devuelta bajo
     -- some circumstances because the terminal digits will be inaccurately reported.
     -- 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 260: Línea 260:
     end
     end


     -- If rounding off, truncate extra digits
     -- Si el redondeo, trunca dígitos adicionales
     if precision < current_precision then
     if precision < current_precision then
         value = z._round( value, precision );
         value = z._round( value, precision );
Línea 269: Línea 269:
     local sign;
     local sign;
      
      
     -- Use proper unary minus sign rather than ASCII default
     -- Usa correctamente menos signo unicode en lugar de ASCII por defecto
     if value < 0 then
     if value < 0 then
         sign = '−';
         sign = '−';
Línea 276: Línea 276:
     end     
     end     
          
          
     -- Handle cases requiring scientific notation
     -- 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
     if string.find( formatted_num, 'E', 1, true ) ~= nil or math.abs(order) >= 9 then
         value = value * math.pow( 10, -order );
         value = value * math.pow( 10, -order );
Línea 287: Línea 287:
     formatted_num = sign .. formatted_num;
     formatted_num = sign .. formatted_num;
      
      
     -- Pad with zeros, if needed    
     -- Pad con ceros si es necesario    
     if current_precision < precision then
     if current_precision < precision then
         local padding;
         local padding;
Línea 311: Línea 311:
     end
     end


     -- Add exponential notation, if necessary.
     -- Añadir notación exponencial, si es necesario
     if order ~= 0 then
     if order ~= 0 then
         -- Use proper unary minus sign rather than ASCII default
         -- Use proper unary minus sign rather than ASCII default

Revisión del 00:48 3 abr 2013

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 = {}

-- Generar 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

Determinar  el orden y la magnitud de los números

Usage:
    {{#invoke: Math | order | value }}
]]
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">Error de formato: l\'orden de magnitud debe ser numérico</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

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

Usage:
    {{ #invoke: Math | precision | value }}
]]
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">Error de formato: el valor de precisión ha de ser numérico</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

Utilizando:
    {{#invoke:Math| max | value1 | value2 | ... }}
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 

Buscar el argumento mínimo

Usando:
    {{#invoke:Math| min | value1 | value2 | ... }}
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

--[[
round

Redondea un número a la precisión especificada

Usando:
    {{#invoke:Math | round | value | precision }}
    
--]]
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">Error de formato: Los valores han de ser numéricos</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.
Usage:
    {{#invoke: Math | precision_format | number | precision }}
]]
function z.precision_format( frame )
    -- Para acceder a Mediawiki incorporado 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">Error de formato: Datos no válidos para redondear</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;
    
    -- Usa correctamente menos signo unicode en lugar de 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ñadir notación exponencial, si es necesario
    if order ~= 0 then
        -- Use proper unary minus sign rather than ASCII default
        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

--[[
Helper function that interprets the input numerically.  If the 
input does not appear to be a number, attempts evaluating it as
a parser functions expression.
]]

function z._cleanNumber( frame, number_string )
    if number_string == nil or number_string:len() == 0 then
        return nil, nil;
    end    
    
    -- Attempt basic conversion
    local number = tonumber( number_string )
    
    -- If failed, attempt to evaluate input as an expression
    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
    -- String is valid but may contain padding, clean it.
        number_string = number_string:match( "^%s*(.-)%s*$" );
    end
    
    return number, number_string;
end

return z