tough-rational
Version:
Rational class using BigInt with fallback to bignumber.js
48 lines (43 loc) • 1.18 kB
JavaScript
;
const abs = require('./abs');
const min = require('../min');
const roughLOB = require('./rough-lob');
const util = require('../util');
const mapToNegative = util.map((v) => -v);
const greatestCommonDenominator = (a, b) => {
a = abs.absNonCoerced(a);
b = abs.absNonCoerced(b);
if (a === b) return a;
if (a === BigInt(0)) return b;
if (b === BigInt(0)) return a;
var c = BigInt(1), d, t;
while (a % BigInt(2) === BigInt(0) && b % BigInt(2) === BigInt(0)) {
d = min(roughLOB(a), roughLOB(b));
a /= d;
b /= d;
c *= d;
}
while (a % BigInt(2) === BigInt(0)) {
a /= roughLOB(a);
}
do {
while (b % BigInt(2) === BigInt(0)) {
b /= roughLOB(b);
}
if (a > b) {
t = b; b = a; a = t;
}
b -= a;
} while (b !== BigInt(0));
return abs.absNonCoerced(c) === BigInt(1) ? a : a * c;
}
const gcdReduce = ([ a, b ]) => {
const greatest = greatestCommonDenominator(a, b);
const retval = [ a / greatest, b / greatest ];
if (retval[0] < BigInt(0) && retval[1] < BigInt(0)) return mapToNegative(retval);
return retval;
};
Object.assign(module.exports, {
greatestCommonDenominator,
gcdReduce
});