tough-rational
Version:
Rational class using BigInt with fallback to bignumber.js
155 lines (143 loc) • 3.5 kB
JavaScript
;
const parse = require('./functions/parse');
const gcd = require('./functions/gcd');
const abs = require('./functions/abs');
const util = require('./util');
const fixtures = require('./fixtures');
const RationalInterfaceProto = require('./interface');
const mapToRational = util.map(Rational);
const mapToPrimitives = util.map(util.method('_getPrimitives'));
const mapToRationalPrimitives = util.flow(mapToRational, mapToPrimitives);
const mapToCoerced = util.map((fn) => (...args) => Rational(gcd.gcdReduce(fn(...mapToRationalPrimitives(args)))));
const mapToNonCoerced = util.map((fn) => (...args) => fn(...mapToRationalPrimitives(args)));
const [
multiply,
dividedBy,
dividedToIntegerBy,
absMethod,
plus,
minus,
pow,
pow10,
div10,
floor,
ceil,
mod,
fractionalComponent,
shiftLeft,
shiftRight,
and,
or,
xor,
round
] = mapToCoerced([
require('./functions/multiply'),
require('./functions/divided-by'),
require('./functions/divided-to-integer-by'),
abs.absPrototypeMethod,
require('./functions/plus'),
require('./functions/minus'),
require('./functions/pow'),
require('./functions/pow10'),
require('./functions/div10'),
require('./functions/floor'),
require('./functions/ceil'),
require('./functions/mod'),
require('./functions/fractional-component'),
require('./functions/shift-left'),
require('./functions/shift-right'),
require('./functions/and'),
require('./functions/or'),
require('./functions/xor'),
require('./functions/round')
]);
const [
isZero,
isNonZero,
eq,
neq,
gt,
geq,
lt,
leq,
isFloatingPoint,
ltZero,
gtZero,
isInfinity,
isFinite,
isNaN,
cmp
] = mapToNonCoerced([
require('./functions/is-zero'),
require('./functions/is-non-zero'),
require('./functions/eq'),
require('./functions/neq'),
require('./functions/gt'),
require('./functions/geq'),
require('./functions/lt'),
require('./functions/leq'),
require('./functions/is-floating-point'),
require('./functions/lt-zero'),
require('./functions/gt-zero'),
require('./functions/is-infinity'),
require('./functions/is-finite'),
require('./functions/is-nan'),
require('./functions/cmp')
]);
const toStringMethod = require('./functions/to-string');
const toString = (rational, decimals = 18) => toStringMethod(rational._getPrimitives(), Rational(decimals)._getPrimitives());
const RationalSuperProto = Object.assign(Object.create(RationalInterfaceProto), {
_getPrimitives() {
return [ this.numerator, this.denominator ];
},
_getDenominator: util.shiftThis(util.property('denominator')),
_getNumerator: util.shiftThis(util.property('numerator')),
_setDenominator: util.setter('denominator'),
_setNumerator: util.setter('numerator')
});
Rational.prototype = Object.assign(Object.create(RationalSuperProto), util.mapToShifted({
multiply,
dividedBy,
dividedToIntegerBy,
abs: absMethod,
plus,
minus,
pow,
pow10,
div10,
toString,
ceil,
floor,
mod,
isFloatingPoint,
fractionalComponent,
isZero,
isNonZero,
eq,
neq,
gt,
geq,
lt,
leq,
ltZero,
gtZero,
isInfinity,
isFinite,
shiftLeft,
shiftRight,
and,
or,
xor,
round,
cmp
}));
util.restoreConstructor(Rational);
function Rational(input) {
if (!(this instanceof Rational)) return new Rational(input);
const [ numerator, denominator ] = parse.parseDynamic(input);
Object.assign(this, {
numerator,
denominator
});
}
module.exports = Rational;