Module:math
- The following documentation is located at Module:math/documentation. [edit]
- Useful links: subpage list • links • transclusions • testcases • sandbox
Various mathematical functions.
Detailed documentation
export.tonumber_finite_real
function export.tonumber_finite_real(n)
A version of tonumber
which only returns finite real numbers. Inputs which would return infinity or NaN
from tonumber
return nil
.
export.is_finite_real_number
function export.is_finite_real_number(n)
Returns true
if the given value is a finite real number, or false
if not.
export.is_integer
function export.is_integer(n)
Returns true
if the given value is an integer, or false
if not.
export.is_positive_integer
function export.is_positive_integer(n, include_0)
Returns true
if the given value is a positive integer (or zero if the include_0
flag is set), or false
if not.
export.log10
function export.log10(x)
Returns the base-10 logarithm of x
.
Should be used instead of math.log10
, which is deprecated and may stop working if Scribunto is updated to a more recent Lua version.
export.to_hex
function export.to_hex(dec)
Converts a decimal number to hexadecimal.
export.gcd
function export.gcd(n, ...)
Returns the greatest common divisor of an arbitrary number of input numbers.
export.lcm
function export.lcm(n, ...)
Returns the least common multiple of an arbitrary number of input numbers.
local export = {}
local format = string.format
local is_integer -- defined as export.is_integer below
local log = math.log
local log10 = math.log10
local select = select
local tonumber = tonumber
local tostring = tostring
local type = type
--[==[
A version of {tonumber} which only returns finite real numbers. Inputs which would return infinity or {NaN} from {tonumber} return {nil}.]==]
function export.tonumber_finite_real(n)
n = tonumber(n)
return n and n - n == 0 and n or nil
end
--[==[
Returns {true} if the given value is a finite real number, or {false} if not.]==]
function export.is_finite_real_number(n)
return n and type(n) == "number" and n - n == 0 -- INF, -INF and NAN fail here.
end
--[==[
Returns {true} if the given value is an integer, or {false} if not.]==]
function export.is_integer(n)
return n and type(n) == "number" and n % 1 == 0 -- INF, -INF and NAN also fail here.
end
is_integer = export.is_integer
--[==[
Returns {true} if the given value is a positive integer (or zero if the `include_0` flag is set), or {false} if not.]==]
function export.is_positive_integer(n, include_0)
return is_integer(n) and (n > 0 or include_0 and n == 0) or false
end
--[==[
Returns the base-10 logarithm of `x`.
Should be used instead of {math.log10}, which is deprecated and may stop working
if Scribunto is updated to a more recent Lua version.]==]
function export.log10(x)
if log10 == nil then
if log(10, 10) == 1 then -- Lua 5.2
function log10(x)
return log(x, 10)
end
else
function log10(x)
return log(x) * 0.43429448190325182765112891891660508229439700580367 -- log10(e)
end
end
end
export.log10 = log10
end
export.log10() -- Sets the actual returned function. (Note: structured like this so that module documentation works.)
local function integer_error(x, param, func_name)
local type_x = type(x)
error(format(
"bad argument #%d to '%s' (integer expected, got %s)",
param, func_name, type_x == "number" and tostring(x) or type_x
), 3)
end
--[==[
Converts a decimal number to hexadecimal.]==]
function export.to_hex(dec)
dec = tonumber(dec) or dec
if not is_integer(dec, true) then
integer_error(dec, 1, "to_hex")
end
local neg = dec < 0
if neg then
dec = -dec
end
-- Inputs >= 2^64 cause string.format to return "0".
if dec >= 18446744073709551616 then
error("integer overflow in 'to_hex': cannot convert inputs with a magnitude greater than or equal to 2^64 (18446744073709551616)", 2)
end
-- string.format treats hex numbers as unsigned, so any sign must be added manually.
return format("%s%X", neg and "-" or "", dec)
end
--[==[
Returns the greatest common divisor of an arbitrary number of input numbers.]==]
function export.gcd(n, ...)
n = tonumber(n) or n
if not is_integer(n) then
integer_error(n, 1, "gcd")
end
local q, args_len, integers = ..., select("#", ...)
-- Compute p_1 = gcd(n_1, n_2), p_2 = gcd(p_1, n_3), ... i.e. compute GCD by Euclid's algorithm for the current result and the next number.
for i = 2, args_len + 1 do
q = tonumber(q) or q
if not is_integer(q) then
integer_error(q, i, "gcd")
elseif n ~= 1 then -- If n is 1, validate remaining inputs.
-- GCD of two integers n, q with Euclid's algorithm.
while q ~= 0 do
n, q = q, n % q
end
end
if i <= args_len then
-- Only create a table if absolutely necessary, as it's inefficient.
if i == 2 then
integers = {...}
end
q = integers[i]
end
end
return n < 0 and -n or n
end
--[==[
Returns the least common multiple of an arbitrary number of input numbers.]==]
function export.lcm(n, ...)
n = tonumber(n) or n
if not is_integer(n) then
integer_error(n, 1, "lcm")
end
local q, args_len, integers = ..., select("#", ...)
-- Compute the product of all inputs as p and GCD as n.
for i = 2, args_len + 1 do
q = tonumber(q) or q
if not is_integer(q) then
integer_error(q, i, "lcm")
elseif n ~= 0 then -- If n is 0, validate remaining inputs.
-- Compute the product.
local p = n * q
-- GCD of two integers n, q with Euclid's algorithm.
while q ~= 0 do
n, q = q, n % q
end
-- Divide product by the GCD to get new LCM.
n = p / n
end
if i <= args_len then
-- Only create a table if absolutely necessary, as it's inefficient.
if i == 2 then
integers = {...}
end
q = integers[i]
end
end
return n < 0 and -n or n
end
return export