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 };