"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * Cannot do Math.log(x) / Math.log(10) bc if IEEE floating point issue * @param x number */ function getMagnitude(x) { // Cannot count string length via Number.toString because it may use scientific notation // for very small or very large numbers. return Math.floor(Math.log(x) * Math.LOG10E); } exports.getMagnitude = getMagnitude; // TODO: dedup with intl-pluralrules // https://tc39.es/proposal-unified-intl-numberformat/section11/numberformat_proposed_out.html#sec-torawfixed function toRawFixed(x, minFraction, maxFraction) { var f = maxFraction; var n; { var exactSolve = x * Math.pow(10, f); var roundDown = Math.floor(exactSolve); var roundUp = Math.ceil(exactSolve); n = exactSolve - roundDown < roundUp - exactSolve ? roundDown : roundUp; } var xFinal = n / Math.pow(10, f); // n is a positive integer, but it is possible to be greater than 1e21. // In such case we will go the slow path. // See also: https://tc39.es/ecma262/#sec-numeric-types-number-tostring var m; if (n < 1e21) { m = n.toString(); } else { m = n.toString(); var idx1 = m.indexOf('.'); var idx2 = m.indexOf('e+'); var exponent = parseInt(m.substring(idx2 + 2), 10); m = m.substring(0, idx1) + m.substring(idx1 + 1, idx2) + repeat('0', exponent - (idx2 - idx1 - 1)); } var int; if (f !== 0) { var k = m.length; if (k <= f) { var z = repeat('0', f + 1 - k); m = z + m; k = f + 1; } var a = m.slice(0, k - f); var b = m.slice(k - f); m = a + "." + b; int = a.length; } else { int = m.length; } var cut = maxFraction - minFraction; while (cut > 0 && m[m.length - 1] === '0') { m = m.slice(0, -1); cut--; } if (m[m.length - 1] === '.') { m = m.slice(0, -1); } return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int }; } exports.toRawFixed = toRawFixed; // https://tc39.es/proposal-unified-intl-numberformat/section11/numberformat_proposed_out.html#sec-torawprecision function toRawPrecision(x, minPrecision, maxPrecision) { var p = maxPrecision; var m; var e; var xFinal; if (x === 0) { m = repeat('0', p); e = 0; xFinal = 0; } else { e = getMagnitude(x); var n = void 0; { var magnitude = e - p + 1; var exactSolve = // Preserve floating point precision as much as possible with multiplication. magnitude < 0 ? x * Math.pow(10, -magnitude) : x / Math.pow(10, magnitude); var roundDown = Math.floor(exactSolve); var roundUp = Math.ceil(exactSolve); n = exactSolve - roundDown < roundUp - exactSolve ? roundDown : roundUp; } // See: https://tc39.es/ecma262/#sec-numeric-types-number-tostring // No need to worry about scientific notation because it only happens for values >= 1e21, // which has 22 significant digits. So it will at least be divided by 10 here to bring the // value back into non-scientific-notation range. m = n.toString(); xFinal = n * Math.pow(10, (e - p + 1)); } var int; if (e >= p - 1) { m = m + repeat('0', e - p + 1); int = e + 1; } else if (e >= 0) { m = m.slice(0, e + 1) + "." + m.slice(e + 1); int = e + 1; } else { m = "0." + repeat('0', -e - 1) + m; int = 1; } if (m.indexOf('.') >= 0 && maxPrecision > minPrecision) { var cut = maxPrecision - minPrecision; while (cut > 0 && m[m.length - 1] === '0') { m = m.slice(0, -1); cut--; } if (m[m.length - 1] === '.') { m = m.slice(0, -1); } } return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int }; } exports.toRawPrecision = toRawPrecision; function repeat(s, times) { if (typeof s.repeat === 'function') { return s.repeat(times); } var arr = new Array(times); for (var i = 0; i < arr.length; i++) { arr[i] = s; } return arr.join(''); } exports.repeat = repeat; //# sourceMappingURL=utils.js.map