UNPKG

7.58 kBJavaScriptView Raw
1/**
2 * Convert a BigNumber to a formatted string representation.
3 *
4 * Syntax:
5 *
6 * format(value)
7 * format(value, options)
8 * format(value, precision)
9 * format(value, fn)
10 *
11 * Where:
12 *
13 * {number} value The value to be formatted
14 * {Object} options An object with formatting options. Available options:
15 * {string} notation
16 * Number notation. Choose from:
17 * 'fixed' Always use regular number notation.
18 * For example '123.40' and '14000000'
19 * 'exponential' Always use exponential notation.
20 * For example '1.234e+2' and '1.4e+7'
21 * 'auto' (default) Regular number notation for numbers
22 * having an absolute value between
23 * `lower` and `upper` bounds, and uses
24 * exponential notation elsewhere.
25 * Lower bound is included, upper bound
26 * is excluded.
27 * For example '123.4' and '1.4e7'.
28 * {number} precision A number between 0 and 16 to round
29 * the digits of the number.
30 * In case of notations 'exponential',
31 * 'engineering', and 'auto',
32 * `precision` defines the total
33 * number of significant digits returned.
34 * In case of notation 'fixed',
35 * `precision` defines the number of
36 * significant digits after the decimal
37 * point.
38 * `precision` is undefined by default.
39 * {number} lowerExp Exponent determining the lower boundary
40 * for formatting a value with an exponent
41 * when `notation='auto`.
42 * Default value is `-3`.
43 * {number} upperExp Exponent determining the upper boundary
44 * for formatting a value with an exponent
45 * when `notation='auto`.
46 * Default value is `5`.
47 * {Function} fn A custom formatting function. Can be used to override the
48 * built-in notations. Function `fn` is called with `value` as
49 * parameter and must return a string. Is useful for example to
50 * format all values inside a matrix in a particular way.
51 *
52 * Examples:
53 *
54 * format(6.4) // '6.4'
55 * format(1240000) // '1.24e6'
56 * format(1/3) // '0.3333333333333333'
57 * format(1/3, 3) // '0.333'
58 * format(21385, 2) // '21000'
59 * format(12e8, {notation: 'fixed'}) // returns '1200000000'
60 * format(2.3, {notation: 'fixed', precision: 4}) // returns '2.3000'
61 * format(52.8, {notation: 'exponential'}) // returns '5.28e+1'
62 * format(12400, {notation: 'engineering'}) // returns '12.400e+3'
63 *
64 * @param {BigNumber} value
65 * @param {Object | Function | number} [options]
66 * @return {string} str The formatted value
67 */
68export function format(value, options) {
69 if (typeof options === 'function') {
70 // handle format(value, fn)
71 return options(value);
72 } // handle special cases
73
74
75 if (!value.isFinite()) {
76 return value.isNaN() ? 'NaN' : value.gt(0) ? 'Infinity' : '-Infinity';
77 } // default values for options
78
79
80 var notation = 'auto';
81 var precision;
82
83 if (options !== undefined) {
84 // determine notation from options
85 if (options.notation) {
86 notation = options.notation;
87 } // determine precision from options
88
89
90 if (typeof options === 'number') {
91 precision = options;
92 } else if (options.precision) {
93 precision = options.precision;
94 }
95 } // handle the various notations
96
97
98 switch (notation) {
99 case 'fixed':
100 return toFixed(value, precision);
101
102 case 'exponential':
103 return toExponential(value, precision);
104
105 case 'engineering':
106 return toEngineering(value, precision);
107
108 case 'auto':
109 {
110 // determine lower and upper bound for exponential notation.
111 // TODO: implement support for upper and lower to be BigNumbers themselves
112 var lowerExp = options && options.lowerExp !== undefined ? options.lowerExp : -3;
113 var upperExp = options && options.upperExp !== undefined ? options.upperExp : 5; // handle special case zero
114
115 if (value.isZero()) return '0'; // determine whether or not to output exponential notation
116
117 var str;
118 var rounded = value.toSignificantDigits(precision);
119 var exp = rounded.e;
120
121 if (exp >= lowerExp && exp < upperExp) {
122 // normal number notation
123 str = rounded.toFixed();
124 } else {
125 // exponential notation
126 str = toExponential(value, precision);
127 } // remove trailing zeros after the decimal point
128
129
130 return str.replace(/((\.\d*?)(0+))($|e)/, function () {
131 var digits = arguments[2];
132 var e = arguments[4];
133 return digits !== '.' ? digits + e : e;
134 });
135 }
136
137 default:
138 throw new Error('Unknown notation "' + notation + '". ' + 'Choose "auto", "exponential", or "fixed".');
139 }
140}
141/**
142 * Format a BigNumber in engineering notation. Like '1.23e+6', '2.3e+0', '3.500e-3'
143 * @param {BigNumber | string} value
144 * @param {number} [precision] Optional number of significant figures to return.
145 */
146
147export function toEngineering(value, precision) {
148 // find nearest lower multiple of 3 for exponent
149 var e = value.e;
150 var newExp = e % 3 === 0 ? e : e < 0 ? e - 3 - e % 3 : e - e % 3; // find difference in exponents, and calculate the value without exponent
151
152 var valueWithoutExp = value.mul(Math.pow(10, -newExp));
153 var valueStr = valueWithoutExp.toPrecision(precision);
154
155 if (valueStr.indexOf('e') !== -1) {
156 valueStr = valueWithoutExp.toString();
157 }
158
159 return valueStr + 'e' + (e >= 0 ? '+' : '') + newExp.toString();
160}
161/**
162 * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3'
163 * @param {BigNumber} value
164 * @param {number} [precision] Number of digits in formatted output.
165 * If not provided, the maximum available digits
166 * is used.
167 * @returns {string} str
168 */
169
170export function toExponential(value, precision) {
171 if (precision !== undefined) {
172 return value.toExponential(precision - 1); // Note the offset of one
173 } else {
174 return value.toExponential();
175 }
176}
177/**
178 * Format a number with fixed notation.
179 * @param {BigNumber} value
180 * @param {number} [precision=undefined] Optional number of decimals after the
181 * decimal point. Undefined by default.
182 */
183
184export function toFixed(value, precision) {
185 return value.toFixed(precision);
186}
\No newline at end of file