Aqbeż għall-kontentut

Module:math

Minn Wikizzjunarju

Documentation for this module may be created at Module:math/doc

local export = {}

local format = string.format
local is_integer -- defined as export.is_integer below
local is_positive_integer -- defined as export.is_positive_integer below
local log = math.log
local log10 = math.log10
local tonumber = tonumber
local type = type

local INF = math.huge
local NEG_INF = -INF

--[==[
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 < INF and n > NEG_INF -- NAN also gets caught here, as it returns false for any comparison.
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, NEG_INF and NAN all get caught here.
end
is_integer = export.is_integer

--[==[
Returns true if the given value is a positive integer, or false if not.]==]
function export.is_positive_integer(n)
	return is_integer(n) and n > 0
end
is_positive_integer = export.is_positive_integer

--[==[
Converts a decimal number to hexadecimal.]==]
function export.to_hex(dec)
	dec = tonumber(dec)
	if not (is_integer(dec) and dec >= 0) then
		error("must be an integer greater than or equal to 0")
	elseif dec >= 18446744073709551616 then
		error("integer overflow") -- string.format returns "0" for numbers >= 2^64
	end
	return format("%X", dec)
end

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
--[==[
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)
	return log10(x)
end
export.log10 = log10

-- GCD of two positive integers p, q with Euclid's algorithm
local function gcd2(p, q)
	repeat
		p, q = q, p % q
	until q == 0
	return p
end

--[==[
Returns the greatest common divisor of all provided positive integers.
]==]
function export.gcd(...)
	local integers = { ... }
	local n = integers[1]
	if not is_positive_integer(n) then
		error("all parameters to gcd(...) must be positive integers", 2)
	end
	
	-- call p_1 = gcd2(n_1, n_2), p_2 = gcd2(p_1, n_3), ... i.e. gcd2 for the current result and the next number
	for i = 2, #integers do
		local q = integers[i]
		if not is_positive_integer(q) then
			error("all parameters to gcd(...) must be positive integers", 2)
		end
		n = gcd2(n, q)
		if n == 1 then break end
	end
	
	return n
end

--[==[
Returns the least common multiple of all provided non-negative integers.
]==]
function export.lcm(...)
	local integers = { ... }
	local n = integers[1]
	if not is_positive_integer(n) then
		if n == 0 then return 0 end
		error("all parameters to lcm(...) must be non-negative integers", 2)
	end
	if #integers == 0 then return n end 
	
	-- compute the product of all inputs as p and gcd as n
	local p = n
	for i = 2, #integers do
		local q = integers[i]
		if not is_positive_integer(q) then
			if q == 0 then return 0 end
			error("all parameters to lcm(...) must be non-negative integers", 2)
		end
		p, n = p * q, gcd2(n, q)
	end
	
	-- and divide product by gcd
	return p / n
end

return export