-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
93 lines (82 loc) · 2.28 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import {merge} from "typescript-object-utils";
const standards = {
si: {
minPrefix: -8,
prefixes: ["y", "z", "a", "f", "p", "n", "μ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y"],
base: 1000
},
iec: {
minPrefix: 0,
prefixes: ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"],
base: 1024
},
bs1852_R: {
minPrefix: 0,
prefixes: ["R", "K", "M", "G", "T"],
base: 1000
},
bs1852_F: {
minPrefix: -4,
prefixes: ["p", "n", "μ", "m", "F"],
base: 1000
}
};
const defaults: PrefixOptions = {
binary: false,
round: 2,
spacer: "",
decimalMark: "."
};
export function prefix(value: number, unit?: string, options?: PrefixOptions): string {
options = merge(defaults, options || {});
let standard;
if (options.bs1852) {
if (unit === "R") {
standard = standards.bs1852_R;
} else if (unit === "F") {
standard = standards.bs1852_F;
} else {
standard = standards.si;
}
} else {
standard = options.binary ? standards.iec : standards.si;
}
let minPrefix = standard.minPrefix;
let prefixes = standard.prefixes;
let maxPrefix = prefixes.length + minPrefix - 1;
let base = standard.base;
let absValue = Math.abs(value);
let exponent = absValue ? Math.floor(Math.log(absValue) / Math.log(base)) : 0;
exponent = Math.min(maxPrefix, Math.max(minPrefix, exponent));
let prefix = prefixes[exponent - minPrefix];
let prefixBase = Math.pow(base, exponent);
let val = value / prefixBase;
let valString = String(val);
unit = unit ? unit : "";
if (options.fixed) {
valString = val.toFixed(options.fixed);
} else if (options.precision) {
valString = val.toPrecision(options.precision);
} else {
let roundPow = Math.pow(10, +options.round);
valString = String(Math.round(val * roundPow) / roundPow);
}
if (options.bs1852) {
const parts = valString.split(".");
if (parts.length == 2) {
return (parts[0] == "0" ? "" : parts[0]) + (prefix ? prefix : (unit ? unit : options.decimalMark)) + (parts[1]);
} else {
return valString + (prefix ? prefix : unit) + (valString.length == 1 ? "0" : "");
}
}
return valString.replace(".", options.decimalMark) + options.spacer + prefix + unit;
}
export interface PrefixOptions {
binary?: boolean;
fixed?: number;
precision?: number;
round?: number;
spacer?: string;
decimalMark?: string;
bs1852?: boolean;
}