Software /
code /
prosody
Comparison
util/human/units.lua @ 10886:994c4a333199
util.human.units: A library for formatting numbers with SI units
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 04 Jan 2019 08:46:26 +0100 |
child | 10888:42a0d9089de9 |
comparison
equal
deleted
inserted
replaced
10885:2f751880767c | 10886:994c4a333199 |
---|---|
1 local large = { | |
2 "k", 1000, | |
3 "M", 1000000, | |
4 "G", 1000000000, | |
5 "T", 1000000000000, | |
6 "P", 1000000000000000, | |
7 "E", 1000000000000000000, | |
8 "Z", 1000000000000000000000, | |
9 "Y", 1000000000000000000000000, | |
10 } | |
11 local small = { | |
12 "m", 0.001, | |
13 "μ", 0.000001, | |
14 "n", 0.000000001, | |
15 "p", 0.000000000001, | |
16 "f", 0.000000000000001, | |
17 "a", 0.000000000000000001, | |
18 "z", 0.000000000000000000001, | |
19 "y", 0.000000000000000000000001, | |
20 } | |
21 | |
22 local binary = { | |
23 "Ki", 2^10, | |
24 "Mi", 2^20, | |
25 "Gi", 2^30, | |
26 "Ti", 2^40, | |
27 "Pi", 2^50, | |
28 "Ei", 2^60, | |
29 "Zi", 2^70, | |
30 "Yi", 2^80, | |
31 } | |
32 | |
33 -- n: number, the number to format | |
34 -- unit: string, the base unit | |
35 -- b: optional enum 'b', thousands base | |
36 local function format(n, unit, b) --> string | |
37 local round = math.floor; | |
38 local prefixes = large; | |
39 local logbase = 1000; | |
40 local fmt = "%.3g %s%s"; | |
41 if n == 0 then | |
42 return fmt:format(n, "", unit); | |
43 end | |
44 if b == 'b' then | |
45 prefixes = binary; | |
46 logbase = 1024; | |
47 elseif n < 1 then | |
48 prefixes = small; | |
49 round = math.ceil; | |
50 end | |
51 local m = math.max(0, math.min(8, round(math.abs(math.log(math.abs(n), logbase))))); | |
52 local prefix, multiplier = table.unpack(prefixes, m * 2-1, m*2); | |
53 return fmt:format(n / (multiplier or 1), prefix or "", unit); | |
54 end | |
55 | |
56 return { | |
57 format = format; | |
58 }; |