Module:Number
From Melvor Idle
Documentation for this module may be created at Module:Number/doc
--
-- Module that contains functions related to numeric formatting or number manipulation
--
local p = {}
local numberSuffixes = {
k = 1e3,
m = 1e6,
b = 1e9,
t = 1e12,
q = 1e15,
s = 1e18,
o = 1e21,
n = 1e24,
d = 1e30
}
--- Formats a number by inserting commas as thousand separators.
-- @param number (number or string) The number to format.
-- @return (string) The formatted number with commas as thousand separators
function p.formatnum(number)
if tonumber(number) == nil then
return number
else
local result = number
while true do
-- Format in blocks of 3 digits at a time until formatting is complete
local k
result, k = string.gsub(result, "^(-?%d+)(%d%d%d)", '%1,%2')
if k == 0 then
break
end
end
return result
end
end
--- Clamps a value between a minimum and maximum range.
-- @param value (number) The value to be clamped.
-- @param min (number) The minimum value in the range.
-- @param max (number) The maximum value in the range.
-- @return (number) The clamped value within the specified range.
function p.clamp(value, min, max)
return math.min(math.max(value, min), max)
end
--- Parses a string representation of a number with suffixes
-- @param str (string) The string to parse.
-- @return (number) The numeric value represented by the input string or 0 if the string is NaN.
function p.parseNumber(str)
-- Empty/nil string.
if not str or str == "" then
return 0
end
-- If the input is already a number, return it.
local number = tonumber(str)
if number then
return number
end
local numStr = str:sub(1, -2)
local suffix = str:sub(-1):lower()
if tonumber(numStr) then
local multiplier = numberSuffixes[suffix] or 1
return numStr * multiplier
else
return 0
end
end
--- Format a number with optional suffixes based on its magnitude.
-- @param number (number) The number to be formatted.
-- @param decimals (number) [optional] The number of decimals to include in the formatted output. Default is 2.
-- @return (string) The formatted number as a string
function p.abbreviateNumber(number, decimals)
if type(number) ~= "number" then
error("NaN")
end
-- Round to two decimals by default.
decimals = decimals or 2
for suffix, value in pairs(numberSuffixes) do
if number >= value then
if number % 1 ~= 0 then
return string.format("%." .. decimals .. "f%s", number / value, suffix)
else
return string.format("%.0f%s", number / value, suffix)
end
end
end
return tostring(number)
end
--- Converts a string to a number or returns a default value if conversion fails.
-- @param str (string) The string to convert to a number.
-- @param def (number) The default value to return if conversion fails or the input is nil.
-- @return (number) The numeric value represented by the input string or the default value if conversion fails.
function p.toNumberOrDefault(str, def)
local num = tonumber(str)
if num then
return num
else
return def
end
end
--- Converts a string to a number or throws an error with a specified message if conversion fails.
-- @param str (string) The string to convert to a number.
-- @param errorMsg (string) [optional] The error message to throw if conversion fails. Defaults to "NaN".
-- @return (number) The numeric value represented by the input string.
-- @throws Error with specified error message if conversion fails.
function p.toNumberOrError(str, errorMsg)
local num = tonumber(str)
local msg = errorMsg
if msg == nil then
msg = "NaN"
end
if num then
return num
else
error(msg)
end
end
return p