Edición de «Módulo:Math»
Ir a la navegación
Ir a la búsqueda
Advertencia: no has iniciado sesión. Tu dirección IP se hará pública si haces cualquier edición. Si inicias sesión o creas una cuenta, tus ediciones se atribuirán a tu nombre de usuario, además de otros beneficios.
Puedes deshacer la edición. Antes de deshacer la edición, comprueba la siguiente comparación para verificar que realmente es lo que quieres hacer, y entonces guarda los cambios para así efectuar la reversión.
Revisión actual | Tu texto | ||
Línea 1: | Línea 1: | ||
--[[ | --[[ | ||
− | + | 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 | |
− | local | + | 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 | end | ||
Línea 107: | Línea 34: | ||
order | order | ||
− | + | Determina el orden y la magnitud de los números | |
− | + | Uso: | |
− | {{#invoke: Math | order | | + | {{#invoke: Math | order | <valor> }} |
]] | ]] | ||
− | + | function z.order(frame) | |
− | function | + | 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 | end | ||
− | + | function z._order(x) | |
− | function | + | if x == 0 then return 0 end |
− | + | return math.floor(math.log10(math.abs(x))) | |
− | |||
end | end | ||
Línea 131: | Línea 58: | ||
precision | precision | ||
− | + | Detemina la precisión de un número usando la representación de cadena | |
− | + | Usar: | |
− | {{ #invoke: Math | precision | | + | {{ #invoke: Math | precision | <valor> }} |
]] | ]] | ||
− | + | function z.precision( frame ) | |
− | function | + | 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 | 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 | end | ||
− | |||
--[[ | --[[ | ||
max | max | ||
− | + | Busca el argumento máximo | |
− | + | Uso: | |
− | {{#invoke:Math| max | | + | {{#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 ) | |
− | function | + | 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 | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | end | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
--[[ | --[[ | ||
− | + | min | |
− | + | Busca el argumento mínimo | |
− | + | Uso: | |
− | {{#invoke:Math| | + | {{#invoke:Math| min | <valor1> | <valor2> | ... }} |
− | + | o | |
− | {{#invoke:Math| | + | {{#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 ) | |
− | function | + | 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 | end | ||
− | function | + | -- 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 | 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 | |
− | end | + | |
− | + | i = i + 1; | |
− | + | end | |
− | + | ||
− | + | return resultado | |
− | |||
− | |||
− | |||
− | |||
end | end | ||
Línea 333: | Línea 247: | ||
round | round | ||
− | + | Redondea un número a la precisión especificada | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | Uso: | ||
+ | {{#invoke:Math | round | <valor> | <precisión> }} | ||
+ | |||
--]] | --]] | ||
− | + | function z.round(frame) | |
− | function | + | 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 | end | ||
− | + | function z._round( value, precision ) | |
− | function | + | local rescale = math.pow( 10, precision ); |
− | + | return math.floor( value * rescale + 0.5 ) / rescale; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
Línea 431: | Línea 273: | ||
precision_format | 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> }} | |
− | {{#invoke: Math | precision_format | | ||
]] | ]] | ||
+ | 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 | 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 | + | 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 | end | ||
− | + | return z | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− |