You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
4.3 KiB

"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