diff options
author | Kim Alvefur <zash@zash.se> | 2019-01-04 08:46:26 +0100 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2019-01-04 08:46:26 +0100 |
commit | 994f59501b9eecf736792d256434ceb7d519adc7 (patch) | |
tree | f50a7955192681d6e54589b128dcdfcfd0561f27 /util/human/units.lua | |
parent | 1f80e42aa5522074c5fa09333307a1c3ce50dc58 (diff) | |
download | prosody-994f59501b9eecf736792d256434ceb7d519adc7.tar.gz prosody-994f59501b9eecf736792d256434ceb7d519adc7.zip |
util.human.units: A library for formatting numbers with SI units
Diffstat (limited to 'util/human/units.lua')
-rw-r--r-- | util/human/units.lua | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/util/human/units.lua b/util/human/units.lua new file mode 100644 index 00000000..2c4662cd --- /dev/null +++ b/util/human/units.lua @@ -0,0 +1,58 @@ +local large = { + "k", 1000, + "M", 1000000, + "G", 1000000000, + "T", 1000000000000, + "P", 1000000000000000, + "E", 1000000000000000000, + "Z", 1000000000000000000000, + "Y", 1000000000000000000000000, +} +local small = { + "m", 0.001, + "μ", 0.000001, + "n", 0.000000001, + "p", 0.000000000001, + "f", 0.000000000000001, + "a", 0.000000000000000001, + "z", 0.000000000000000000001, + "y", 0.000000000000000000000001, +} + +local binary = { + "Ki", 2^10, + "Mi", 2^20, + "Gi", 2^30, + "Ti", 2^40, + "Pi", 2^50, + "Ei", 2^60, + "Zi", 2^70, + "Yi", 2^80, +} + +-- n: number, the number to format +-- unit: string, the base unit +-- b: optional enum 'b', thousands base +local function format(n, unit, b) --> string + local round = math.floor; + local prefixes = large; + local logbase = 1000; + local fmt = "%.3g %s%s"; + if n == 0 then + return fmt:format(n, "", unit); + end + if b == 'b' then + prefixes = binary; + logbase = 1024; + elseif n < 1 then + prefixes = small; + round = math.ceil; + end + local m = math.max(0, math.min(8, round(math.abs(math.log(math.abs(n), logbase))))); + local prefix, multiplier = table.unpack(prefixes, m * 2-1, m*2); + return fmt:format(n / (multiplier or 1), prefix or "", unit); +end + +return { + format = format; +}; |