UNPKG

algebra.js

Version:

Build, display, and solve algebraic equations.

208 lines (162 loc) 5.25 kB
var isInt = require('./helper').isInt; var gcd = require('./helper').gcd; var lcm = require('./helper').lcm; var Fraction = function(a, b) { if (b === 0) { throw new EvalError("Divide By Zero"); } else if (isInt(a) && isInt(b)) { this.numer = a; this.denom = b; } else { throw new TypeError("Invalid Argument ("+a.toString()+ ","+ b.toString() +"): Divisor and dividend must be of type Integer."); } }; Fraction.prototype.copy = function() { return new Fraction(this.numer, this.denom); }; Fraction.prototype.reduce = function() { var copy = this.copy(); var g = gcd(copy.numer, copy.denom); copy.numer = copy.numer / g; copy.denom = copy.denom / g; if (Math.sign(copy.denom) == -1 && Math.sign(copy.numer) == 1) { copy.numer *= -1; copy.denom *= -1; } return copy; }; Fraction.prototype.equalTo = function(fraction) { if(fraction instanceof Fraction) { var thisReduced = this.reduce(); var thatReduced = fraction.reduce(); return thisReduced.numer === thatReduced.numer && thisReduced.denom === thatReduced.denom; }else{ return false; } }; Fraction.prototype.add = function(f, simplify) { simplify = (simplify === undefined ? true : simplify); var a, b; if (f instanceof Fraction) { a = f.numer; b = f.denom; } else if (isInt(f)) { a = f; b = 1; } else { throw new TypeError("Invalid Argument (" + f.toString() + "): Summand must be of type Fraction or Integer."); } var copy = this.copy(); if (this.denom == b) { copy.numer += a; } else { var m = lcm(copy.denom, b); var thisM = m / copy.denom; var otherM = m / b; copy.numer *= thisM; copy.denom *= thisM; a *= otherM; copy.numer += a; } return (simplify ? copy.reduce() : copy); }; Fraction.prototype.subtract = function(f, simplify) { simplify = (simplify === undefined ? true : simplify); var copy = this.copy(); if (f instanceof Fraction) { return copy.add(new Fraction(-f.numer, f.denom), simplify); } else if (isInt(f)) { return copy.add(new Fraction(-f, 1), simplify); } else { throw new TypeError("Invalid Argument (" + f.toString() + "): Subtrahend must be of type Fraction or Integer."); } }; Fraction.prototype.multiply = function(f, simplify) { simplify = (simplify === undefined ? true : simplify); var a, b; if (f instanceof Fraction) { a = f.numer; b = f.denom; } else if (isInt(f) && f) { a = f; b = 1; } else if (f === 0) { a = 0; b = 1; } else { throw new TypeError("Invalid Argument (" + f.toString() + "): Multiplicand must be of type Fraction or Integer."); } var copy = this.copy(); copy.numer *= a; copy.denom *= b; return (simplify ? copy.reduce() : copy); }; Fraction.prototype.divide = function(f, simplify) { simplify = (simplify === undefined ? true : simplify); if (f.valueOf() === 0) { throw new EvalError("Divide By Zero"); } var copy = this.copy(); if (f instanceof Fraction) { return copy.multiply(new Fraction(f.denom, f.numer), simplify); } else if (isInt(f)) { return copy.multiply(new Fraction(1, f), simplify); } else { throw new TypeError("Invalid Argument (" + f.toString() + "): Divisor must be of type Fraction or Integer."); } }; Fraction.prototype.pow = function(n, simplify) { simplify = (simplify === undefined ? true : simplify); var copy = this.copy(); copy.numer = Math.pow(copy.numer, n); copy.denom = Math.pow(copy.denom, n); return (simplify ? copy.reduce() : copy); }; Fraction.prototype.abs = function() { var copy = this.copy(); copy.numer = Math.abs(copy.numer); copy.denom = Math.abs(copy.denom); return copy; }; Fraction.prototype.valueOf = function() { return this.numer / this.denom; }; Fraction.prototype.toString = function() { if (this.numer === 0) { return "0"; } else if (this.denom === 1) { return this.numer.toString(); } else if (this.denom === -1) { return (-this.numer).toString(); } else { return this.numer + "/" + this.denom; } }; Fraction.prototype.toTex = function() { if (this.numer === 0) { return "0"; } else if (this.denom === 1) { return this.numer.toString(); } else if (this.denom === -1) { return (-this.numer).toString(); } else { return "\\frac{" + this.numer + "}{" + this.denom + "}"; } }; Fraction.prototype._squareRootIsRational = function() { if (this.valueOf() === 0) { return true; } var sqrtNumer = Math.sqrt(this.numer); var sqrtDenom = Math.sqrt(this.denom); return isInt(sqrtNumer) && isInt(sqrtDenom); }; Fraction.prototype._cubeRootIsRational = function() { if (this.valueOf() === 0) { return true; } var cbrtNumer = Math.cbrt(this.numer); var cbrtDenom = Math.cbrt(this.denom); return isInt(cbrtNumer) && isInt(cbrtDenom); }; module.exports = Fraction;