tough-rational
Version:
Rational class using BigInt with fallback to bignumber.js
32 lines (25 loc) • 1.29 kB
JavaScript
;
const strip = require('../strip');
const util = require('../util');
const powGenerator = require('./pow-generator');
const pow = powGenerator();
const compat = require('../compat');
const PRECISION_PADDING = compat.testForBigInt() ? BigInt(1000) : 1000;
const maybeAddLeadingZero = (s) => {
if (util.first(s) === '.') return '0' + s;
return s;
};
const defaultToZero = (s) => !String(s) ? '0' : s;
const toString = ([ aNum, aDen ], [ bNum, bDen ]) => {
const decimals = bNum / bDen;
const zeroes = BigInt(decimals) + PRECISION_PADDING;
const precisionCliff = pow(BigInt(10), zeroes);
const factor = precisionCliff / aDen;
const digits = [].slice.call(String(aNum * factor));
const insertDecimalAt = digits.length - Number(zeroes);
const joined = insertDecimalAt < 0 ? ['.'].concat(Array.apply(null, { length: Math.abs(insertDecimalAt) }).map(() => 0)).concat(digits).join('') : digits.slice(0, insertDecimalAt).concat('.').concat(digits.slice(insertDecimalAt)).join('');
const decimalPosition = joined.lastIndexOf('.');
if (!~decimalPosition) return maybeAddLeadingZero(strip.stripZeroes(joined));
return defaultToZero(maybeAddLeadingZero(strip.stripZeroes(joined.substr(0, decimalPosition + 1 + Number(decimals)))));
};
module.exports = toString;