123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.format = format;
- exports.toEngineering = toEngineering;
- exports.toExponential = toExponential;
- exports.toFixed = toFixed;
- var _number = require("../number.js");
- /**
- * Formats a BigNumber in a given base
- * @param {BigNumber} n
- * @param {number} base
- * @param {number} size
- * @returns {string}
- */
- function formatBigNumberToBase(n, base, size) {
- var BigNumberCtor = n.constructor;
- var big2 = new BigNumberCtor(2);
- var suffix = '';
- if (size) {
- if (size < 1) {
- throw new Error('size must be in greater than 0');
- }
- if (!(0, _number.isInteger)(size)) {
- throw new Error('size must be an integer');
- }
- if (n.greaterThan(big2.pow(size - 1).sub(1)) || n.lessThan(big2.pow(size - 1).mul(-1))) {
- throw new Error("Value must be in range [-2^".concat(size - 1, ", 2^").concat(size - 1, "-1]"));
- }
- if (!n.isInteger()) {
- throw new Error('Value must be an integer');
- }
- if (n.lessThan(0)) {
- n = n.add(big2.pow(size));
- }
- suffix = "i".concat(size);
- }
- switch (base) {
- case 2:
- return "".concat(n.toBinary()).concat(suffix);
- case 8:
- return "".concat(n.toOctal()).concat(suffix);
- case 16:
- return "".concat(n.toHexadecimal()).concat(suffix);
- default:
- throw new Error("Base ".concat(base, " not supported "));
- }
- }
- /**
- * 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'.
- * 'bin', 'oct, or
- * 'hex' Format the number using binary, octal,
- * or hexadecimal notation.
- * For example '0b1101' and '0x10fe'.
- * {number} wordSize The word size in bits to use for formatting
- * in binary, octal, or hexadecimal notation.
- * To be used only with 'bin', 'oct', or 'hex'
- * values for 'notation' option. When this option
- * is defined the value is formatted as a signed
- * twos complement integer of the given word size
- * and the size suffix is appended to the output.
- * For example
- * format(-1, {notation: 'hex', wordSize: 8}) === '0xffi8'.
- * Default value is undefined.
- * {number} precision A number between 0 and 16 to round
- * the digits of the number.
- * In case of notations 'exponential',
- * 'engineering', 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
- */
- function format(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;
- var wordSize;
- 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;
- }
- if (options.wordSize) {
- wordSize = options.wordSize;
- if (typeof wordSize !== 'number') {
- throw new Error('Option "wordSize" must be a number');
- }
- }
- }
- // handle the various notations
- switch (notation) {
- case 'fixed':
- return toFixed(value, precision);
- case 'exponential':
- return toExponential(value, precision);
- case 'engineering':
- return toEngineering(value, precision);
- case 'bin':
- return formatBigNumberToBase(value, 2, wordSize);
- case 'oct':
- return formatBigNumberToBase(value, 8, wordSize);
- case 'hex':
- return formatBigNumberToBase(value, 16, wordSize);
- case 'auto':
- {
- // 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 rounded = value.toSignificantDigits(precision);
- var exp = rounded.e;
- if (exp >= lowerExp && exp < upperExp) {
- // normal number notation
- str = rounded.toFixed();
- } else {
- // exponential notation
- str = 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", "fixed", "bin", "oct", or "hex.');
- }
- }
- /**
- * Format a BigNumber in engineering notation. Like '1.23e+6', '2.3e+0', '3.500e-3'
- * @param {BigNumber | string} value
- * @param {number} [precision] Optional number of significant figures to return.
- */
- function toEngineering(value, precision) {
- // find nearest lower multiple of 3 for exponent
- var e = value.e;
- 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
- var valueWithoutExp = value.mul(Math.pow(10, -newExp));
- var valueStr = valueWithoutExp.toPrecision(precision);
- if (valueStr.indexOf('e') !== -1) {
- valueStr = valueWithoutExp.toString();
- }
- return valueStr + 'e' + (e >= 0 ? '+' : '') + newExp.toString();
- }
- /**
- * 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
- */
- function toExponential(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.
- */
- function toFixed(value, precision) {
- return value.toFixed(precision);
- }
|