UNPKG

tough-rational

Version:

Rational class using BigInt with fallback to bignumber.js

161 lines (144 loc) 3.36 kB
'use strict'; const BN = require('bignumber.js'); const util = require('./util'); const RationalInterfaceProto = require('./interface'); const parse = require('./fallback/parse'); BN.config({ ERRORS: false, DECIMAL_PLACES: 100 }); const mapCastToRational = util.map((v) => new Rational(v)); const mapToEncapsulatedRational = util.map(util.method('_getEncapsulatedRational')); const castAndMapToEncapsulatedRational = util.flow(mapCastToRational, mapToEncapsulatedRational); const createRational = (v) => new Rational(v); const castResultToRational = (fn) => (...args) => createRational(fn(...args)); const toNonCoerced = (fn) => (...args) => fn(...castAndMapToEncapsulatedRational(args)); const toCoerced = util.flow(toNonCoerced, castResultToRational); const mapToNonCoerced = util.map(toNonCoerced); const mapToCoerced = util.map(toCoerced); const maybeCoerceToRational = (n) => n instanceof BN ? new Rational(n) : typeof n === 'string' && n.replace(/,/g, '') || n; const RationalSuperProto = Object.assign(Object.create(RationalInterfaceProto), { _getEncapsulatedRational: util.shiftThis(util.property('_rational')), _setEncapsulatedRational: util.setter('_rational') }); const toShimmedMethod = (name) => (a, b) => a[name](b); const mapToShimmedMethod = util.map(toShimmedMethod); const [ multiply, dividedBy, dividedToIntegerBy, plus, minus, pow, mod ] = mapToCoerced(mapToShimmedMethod([ 'multipliedBy', 'div', 'dividedToIntegerBy', 'plus', 'minus', 'pow', 'mod' ])); const [ isZero, eq, gt, geq, lt, leq, isFinite, isNaN, cmp ] = mapToNonCoerced(mapToShimmedMethod([ 'isZero', 'eq', 'gt', 'gte', 'lt', 'lte', 'isFinite', 'isNaN', 'comparedTo' ])); const [ abs, pow10, div10, fractionalComponent, floor, ceil, shiftLeft, shiftRight, round ] = mapToCoerced([ require('./fallback/abs'), require('./fallback/pow10'), require('./fallback/div10'), require('./fallback/fractional-component'), require('./fallback/floor'), require('./fallback/ceil'), require('./fallback/shift-left'), require('./fallback/shift-right'), require('./fallback/round') ]); const [ isNonZero, neq, isFloatingPoint, ltZero, gtZero, isInfinity, toString, toHexString ] = mapToNonCoerced([ require('./fallback/is-non-zero'), require('./fallback/neq'), require('./fallback/is-floating-point'), require('./fallback/lt-zero'), require('./fallback/gt-zero'), require('./fallback/is-infinity'), require('./fallback/to-string'), require('./fallback/to-hex-string') ]); function Rational(input) { if (!(this instanceof Rational)) return new Rational(input); this._setEncapsulatedRational(parse.parseDynamic(input)); } const toDecimalFallback = require('./fallback/to-decimal'); Rational.prototype = Object.assign(Object.create(RationalSuperProto), util.mapToShifted({ multiply, dividedBy, dividedToIntegerBy, abs, plus, minus, pow, floor, ceil, mod, isZero, eq, gt, geq, lt, leq, isFinite, isNaN, abs, pow10, div10, fractionalComponent, isNonZero, neq, isFloatingPoint, ltZero, gtZero, isInfinity, toString, shiftLeft, shiftRight, toHexString, round, cmp, toDecimal: toNonCoerced(toDecimalFallback) })); util.restoreConstructor(Rational); module.exports = Rational;