UNPKG

mathjs

Version:

Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser with support for symbolic computation, comes with a large set of built-in functions and constants, and offers an integrated solution to work with dif

186 lines (169 loc) 7.91 kB
/** * Convert a BigNumber to a formatted string representation. * * Syntax: * * format(value) * format(value, options) * format(value, precision) * format(value, fn) * * Where: * * {number} value The value to be formatted * {Object} options An object with formatting options. Available options: * {string} notation * Number notation. Choose from: * 'fixed' Always use regular number notation. * For example '123.40' and '14000000' * 'exponential' Always use exponential notation. * For example '1.234e+2' and '1.4e+7' * 'auto' (default) Regular number notation for numbers * having an absolute value between * `lower` and `upper` bounds, and uses * exponential notation elsewhere. * Lower bound is included, upper bound * is excluded. * For example '123.4' and '1.4e7'. * {number} precision A number between 0 and 16 to round * the digits of the number. * In case of notations 'exponential' and * 'auto', `precision` defines the total * number of significant digits returned. * In case of notation 'fixed', * `precision` defines the number of * significant digits after the decimal * point. * `precision` is undefined by default. * {number} lowerExp Exponent determining the lower boundary * for formatting a value with an exponent * when `notation='auto`. * Default value is `-3`. * {number} upperExp Exponent determining the upper boundary * for formatting a value with an exponent * when `notation='auto`. * Default value is `5`. * {Function} fn A custom formatting function. Can be used to override the * built-in notations. Function `fn` is called with `value` as * parameter and must return a string. Is useful for example to * format all values inside a matrix in a particular way. * * Examples: * * format(6.4); // '6.4' * format(1240000); // '1.24e6' * format(1/3); // '0.3333333333333333' * format(1/3, 3); // '0.333' * format(21385, 2); // '21000' * format(12e8, {notation: 'fixed'}); // returns '1200000000' * format(2.3, {notation: 'fixed', precision: 4}); // returns '2.3000' * format(52.8, {notation: 'exponential'}); // returns '5.28e+1' * format(12400, {notation: 'engineering'}); // returns '12.400e+3' * * @param {BigNumber} value * @param {Object | Function | number} [options] * @return {string} str The formatted value */ exports.format = function (value, options) { if (typeof options === 'function') { // handle format(value, fn) return options(value); } // handle special cases if (!value.isFinite()) { return value.isNaN() ? 'NaN' : (value.gt(0) ? 'Infinity' : '-Infinity'); } // default values for options var notation = 'auto'; var precision = undefined; if (options !== undefined) { // determine notation from options if (options.notation) { notation = options.notation; } // determine precision from options if (typeof options === 'number') { precision = options; } else if (options.precision) { precision = options.precision; } } // handle the various notations switch (notation) { case 'fixed': return exports.toFixed(value, precision); case 'exponential': return exports.toExponential(value, precision); case 'auto': // TODO: clean up some day. Deprecated since: 2018-01-24 // @deprecated upper and lower are replaced with upperExp and lowerExp since v4.0.0 if (options && options.exponential && (options.exponential.lower !== undefined || options.exponential.upper !== undefined)) { var fixedOptions = Object.assign({}, options); fixedOptions.exponential = undefined; if (options.exponential.lower !== undefined) { fixedOptions.lowerExp = Math.round(Math.log(options.exponential.lower) / Math.LN10); } if (options.exponential.upper !== undefined) { fixedOptions.upperExp = Math.round(Math.log(options.exponential.upper) / Math.LN10); } console.warn('Deprecation warning: Formatting options exponential.lower and exponential.upper ' + '(minimum and maximum value) ' + 'are replaced with exponential.lowerExp and exponential.upperExp ' + '(minimum and maximum exponent) since version 4.0.0. ' + 'Replace ' + JSON.stringify(options) + ' with ' + JSON.stringify(fixedOptions)); return exports.format(value, fixedOptions); } // determine lower and upper bound for exponential notation. // TODO: implement support for upper and lower to be BigNumbers themselves var lowerExp = (options && options.lowerExp !== undefined) ? options.lowerExp : -3; var upperExp = (options && options.upperExp !== undefined) ? options.upperExp : 5; // handle special case zero if (value.isZero()) return '0'; // determine whether or not to output exponential notation var str; var exp = value.logarithm(); if (exp.gte(lowerExp) && exp.lt(upperExp)) { // normal number notation str = value.toSignificantDigits(precision).toFixed(); } else { // exponential notation str = exports.toExponential(value, precision); } // remove trailing zeros after the decimal point return str.replace(/((\.\d*?)(0+))($|e)/, function () { var digits = arguments[2]; var e = arguments[4]; return (digits !== '.') ? digits + e : e; }); default: throw new Error('Unknown notation "' + notation + '". ' + 'Choose "auto", "exponential", or "fixed".'); } }; /** * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3' * @param {BigNumber} value * @param {number} [precision] Number of digits in formatted output. * If not provided, the maximum available digits * is used. * @returns {string} str */ exports.toExponential = function (value, precision) { if (precision !== undefined) { return value.toExponential(precision - 1); // Note the offset of one } else { return value.toExponential(); } }; /** * Format a number with fixed notation. * @param {BigNumber} value * @param {number} [precision=undefined] Optional number of decimals after the * decimal point. Undefined by default. */ exports.toFixed = function (value, precision) { return value.toFixed(precision); };