UNPKG

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