918
edits
m (Add functions for numeric parsing with suffixes (k, m, b, etc)) |
No edit summary |
||
(14 intermediate revisions by the same user not shown) | |||
Line 16: | Line 16: | ||
d = 1e30 | d = 1e30 | ||
} | } | ||
local function sigfig(x, y) | |||
local x_sign = x < 0 and -1 or 1 | |||
local x = math.abs(x) | |||
local n = math.floor(math.log10(x)) + 1 - y | |||
return x_sign * math.pow(10, n) * p.round2(x / math.pow(10, n), 0) | |||
end | |||
-- Automatically rounds to 2 places from the significant figure. | |||
-- Taken from RSWiki. | |||
function p.autoround(x) | |||
x = tonumber(x) or 0 | |||
local _x | |||
if x == 0 then | |||
_x = 0 | |||
elseif math.abs(x) < 0.1 then | |||
_x = sigfig(x, 2) | |||
elseif math.abs(x) > 999 then | |||
_x = p.round2(x, 0) | |||
else | |||
_x = p.round2(x, 2) | |||
end | |||
return _x | |||
end | |||
--- 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 | |||
end | |||
-- Find out of the number is using scientific notation. | |||
-- If it is, convert it to a string and remove the trailing zeroes. | |||
local result = tostring(number) | |||
if result:find("[eE]") ~= nil then | |||
result = string.format("%.20f", number) | |||
result = result:gsub("%.?0*$", "") | |||
end | |||
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 | |||
--- Rounds a number to a specified number of digits after the decimal point. | |||
-- @param val (number or string) The value to round. | |||
-- @param maxDigits (number) [optional] The maximum number of digits after the decimal point. | |||
-- @param minDigits (number) [optional] The minimum number of digits after the decimal point. | |||
-- @return (string) The rounded number with the specified number of digits after the decimal point, or the input unchanged if it's not a number. | |||
function p.round(val, maxDigits, minDigits) | |||
if val == nil then | |||
return nil | |||
else | |||
if type(maxDigits) == "table" then | |||
minDigits = maxDigits[2] | |||
maxDigits = maxDigits[1] | |||
end | |||
local result = val.."" | |||
local decimals = string.find(result, "%.") | |||
if decimals ~= nil then | |||
decimals = string.len(result) - decimals | |||
else | |||
decimals = 0 | |||
end | |||
if maxDigits ~= nil and decimals > maxDigits then | |||
result = string.format("%."..maxDigits.."f", result) | |||
elseif minDigits ~= nil and decimals < minDigits then | |||
result = string.format("%."..minDigits.."f", result) | |||
end | |||
return result | |||
end | |||
end | |||
--- Rounds a number to a specified number of decimal places. | |||
-- @param num (number) The number to round. | |||
-- @param numDecimalPlaces (number) [optional] The number of decimal places to round to. | |||
-- @return (number) The rounded number with the specified number of decimal places, or the nearest integer if numDecimalPlaces is not provided. | |||
--From http://lua-users.org/wiki/SimpleRound | |||
function p.round2(num, numDecimalPlaces) | |||
local mult = 10^(numDecimalPlaces or 0) | |||
return math.floor(num * mult + 0.5) / mult | |||
end | |||
-- Euclidean Greatest Common Divisor algorithm | |||
function p.gcd(a, b) | |||
if b ~= 0 then | |||
return p.gcd(b, a % b) | |||
else | |||
return math.abs(a) | |||
end | |||
end | |||
--Formats a pair of numbers as a reduced fraction | |||
function p.fraction(n, d) | |||
local gcd = p.gcd(n, d) | |||
return p.formatnum(n/gcd)..'/'..p.formatnum(d/gcd) | |||
end | |||
--Similar to p.fraction but returns the simplified numerator and denomerator separately without formatting | |||
function p.fractionpair(n, d) | |||
local gcd = p.gcd(n, d) | |||
return n / gcd, d / gcd | |||
end | |||
--Returns a number including the sign, even if positive | |||
function p.numStrWithSign(number) | |||
if number >= 0 then | |||
return '+'..p.formatnum(number) | |||
else | |||
return p.formatnum(number) | |||
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 | --- Parses a string representation of a number with suffixes | ||
-- @param str (string) The string to parse. | -- @param str (string) The string to parse. | ||
Line 65: | Line 197: | ||
return tostring(number) | 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 | |||
-- Returns the probability of getting at least one drop, provided | |||
-- the drop rate and the current amount of drops. | |||
function p.getDropProbability(dropRate, totalDrops) | |||
dropRate = p.clamp(dropRate, 0, 1) | |||
return 1 - (1- dropRate) ^ 500 | |||
end | |||
-- Returns the amount of drops required for a certain drop probability. | |||
function p.getDropsForProbability(dropRate, probability) | |||
dropRate = p.clamp(dropRate, 0, 1) | |||
probability = p.clamp(probability, 0, 1) | |||
return math.log(1 - probability) / math.log(1 - dropRate) | |||
end | end | ||
return p | return p |
edits