mirror of
https://github.com/Brandon-Rozek/Fractions.js.git
synced 2024-11-09 11:10:34 -05:00
206 lines
6.3 KiB
JavaScript
206 lines
6.3 KiB
JavaScript
|
var Fraction = function() {
|
||
|
this.numerator;
|
||
|
this.denominator;
|
||
|
|
||
|
var numerator = 0;
|
||
|
var denominator = 1;
|
||
|
var frac;
|
||
|
|
||
|
//If two numbers-like arguments are passed into the function
|
||
|
if (!isNaN(arguments[0]) && !isNaN(arguments[1])) {
|
||
|
numerator = Number(arguments[0]);
|
||
|
denominator = Number(arguments[1]);
|
||
|
|
||
|
}
|
||
|
//Only a single number is present
|
||
|
else if (!isNaN(arguments[0])) {
|
||
|
numerator = Number(arguments[0]);
|
||
|
}
|
||
|
//If a string is passed into the function
|
||
|
else if (Fraction.isString(arguments[0])) {
|
||
|
var number = arguments[0];
|
||
|
if (number.indexOf('/') != -1) {
|
||
|
numerator = Number(number.substring(0, number.indexOf('/')));
|
||
|
denominator = Number(number.substring(number.indexOf('/') + 1, number.length));
|
||
|
} else {
|
||
|
numerator = number;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
throw new Error("Arguments invalid");
|
||
|
}
|
||
|
|
||
|
if (!Number.isInteger(numerator) || !Number.isInteger(denominator)) {
|
||
|
if (!Number.isInteger(numerator)) { numerator = Fraction.decimalToFraction(numerator); }
|
||
|
if (!Number.isInteger(denominator)) { denominator = Fraction.decimalToFraction(denominator); }
|
||
|
frac = Fraction.divide(numerator, denominator);
|
||
|
numerator = frac.numerator;
|
||
|
denominator = frac.denominator;
|
||
|
}
|
||
|
if (denominator == 0) {
|
||
|
throw new Error("Cannot divide by zero");
|
||
|
}
|
||
|
|
||
|
this.numerator = numerator;
|
||
|
this.denominator = denominator;
|
||
|
|
||
|
this.simplify();
|
||
|
|
||
|
}
|
||
|
|
||
|
Fraction.prototype.multiply = function(frac) {
|
||
|
Fraction.correctArgumentLength(1, arguments.length);
|
||
|
return Fraction.change(this, Fraction.multiply(this, frac));
|
||
|
}
|
||
|
Fraction.prototype.divide = function(frac) {
|
||
|
Fraction.correctArgumentLength(1, arguments.length);
|
||
|
return Fraction.change(this, Fraction.divide(this, frac));
|
||
|
}
|
||
|
Fraction.prototype.add = function(frac) {
|
||
|
Fraction.correctArgumentLength(1, arguments.length);
|
||
|
return Fraction.change(this, Fraction.add(this, frac));
|
||
|
}
|
||
|
Fraction.prototype.subtract = function(frac) {
|
||
|
Fraction.correctArgumentLength(1, arguments.length);
|
||
|
return Fraction.change(this, Fraction.subtract(this, frac));
|
||
|
}
|
||
|
Fraction.prototype.simplify = function() {
|
||
|
Fraction.correctArgumentLength(0, arguments.length);
|
||
|
return Fraction.change(this, Fraction.simplify(this));
|
||
|
}
|
||
|
Fraction.prototype.toString = function() {
|
||
|
return Fraction.toString(this);
|
||
|
}
|
||
|
Fraction.prototype.equals = function(frac) {
|
||
|
return Fraction.equals(this, frac);
|
||
|
}
|
||
|
Fraction.prototype.valueOf = function() {
|
||
|
return Fraction.valueOf(this);
|
||
|
}
|
||
|
|
||
|
Fraction.add = function(frac1, frac2) {
|
||
|
Fraction.correctArgumentLength(2, arguments.length);
|
||
|
frac1 = Fraction.toFraction(frac1)
|
||
|
frac2 = Fraction.toFraction(frac2)
|
||
|
|
||
|
var newFrac = frac1;
|
||
|
newFrac.numerator = frac1.numerator * frac2.denominator + frac1.denominator * frac2.numerator;
|
||
|
newFrac.denominator = frac1.denominator * frac2.denominator;
|
||
|
return Fraction.simplify(newFrac);
|
||
|
}
|
||
|
Fraction.subtract = function(frac1, frac2) {
|
||
|
Fraction.correctArgumentLength(2, arguments.length);
|
||
|
frac1 = Fraction.toFraction(frac1);
|
||
|
frac2 = Fraction.toFraction(frac2);
|
||
|
|
||
|
var newFrac = frac1;
|
||
|
newFrac.numerator = frac1.numerator * frac2.denominator - frac1.denominator * frac2.numerator;
|
||
|
newFrac.denominator = frac1.denominator * frac2.denominator;
|
||
|
return Fraction.simplify(newFrac);
|
||
|
}
|
||
|
Fraction.multiply = function(frac1, frac2) {
|
||
|
Fraction.correctArgumentLength(2, arguments.length);
|
||
|
frac1 = Fraction.toFraction(frac1);
|
||
|
frac2 = Fraction.toFraction(frac2);
|
||
|
|
||
|
var newFrac = frac1;
|
||
|
newFrac.numerator = frac1.numerator * frac2.numerator;
|
||
|
newFrac.denominator = frac1.denominator * frac2.denominator;
|
||
|
return Fraction.simplify(newFrac);
|
||
|
}
|
||
|
Fraction.divide = function(frac1, frac2) {
|
||
|
Fraction.correctArgumentLength(2, arguments.length);
|
||
|
frac1 = Fraction.toFraction(frac1);
|
||
|
frac2 = Fraction.toFraction(frac2);
|
||
|
|
||
|
var newFrac = frac1;
|
||
|
newFrac.numerator = frac1.numerator * frac2.denominator;
|
||
|
newFrac.denominator = frac1.denominator * frac2.numerator;
|
||
|
return Fraction.simplify(newFrac);
|
||
|
}
|
||
|
|
||
|
Fraction.simplify = function(frac) {
|
||
|
Fraction.correctArgumentLength(1, arguments.length);
|
||
|
frac = Fraction.toFraction(frac);
|
||
|
|
||
|
var gcd = Fraction.greatestCommonDivisor(frac.numerator, frac.denominator);
|
||
|
if (gcd == 1) { return frac; }
|
||
|
frac.numerator /= gcd;
|
||
|
frac.denominator /= gcd;
|
||
|
return frac;
|
||
|
}
|
||
|
Fraction.greatestCommonDivisor = function(num1, num2) {
|
||
|
var greater;
|
||
|
var lesser;
|
||
|
|
||
|
num1 = Math.abs(num1);
|
||
|
num2 = Math.abs(num2);
|
||
|
greater = Math.max(num1, num2);
|
||
|
lesser = Math.min(num1, num2);
|
||
|
|
||
|
while (lesser != 0) {
|
||
|
var t = lesser;
|
||
|
lesser = greater % lesser;
|
||
|
greater = t;
|
||
|
}
|
||
|
return greater;
|
||
|
}
|
||
|
Fraction.toString = function(frac) {
|
||
|
Fraction.correctArgumentLength(1, arguments.length);
|
||
|
if (frac.denominator == 1) { return "" + frac.numerator; }
|
||
|
return "" + frac.numerator + "/" + frac.denominator;
|
||
|
}
|
||
|
Fraction.equals = function(frac1, frac2) {
|
||
|
Fraction.correctArgumentLength(2, arguments.length);
|
||
|
frac1 = Fraction.toFraction(frac1);
|
||
|
frac2 = Fraction.toFraction(frac2);
|
||
|
|
||
|
frac1 = Fraction.simplify(frac1);
|
||
|
frac2 = Fraction.simplify(frac2);
|
||
|
return frac1.numerator == frac2.numerator && frac1.denominator == frac2.denominator;
|
||
|
}
|
||
|
Fraction.valueOf = function(frac) {
|
||
|
Fraction.correctArgumentLength(1, arguments.length);
|
||
|
frac = Fraction.toFraction(frac);
|
||
|
return frac.numerator / frac.denominator;
|
||
|
}
|
||
|
Fraction.correctArgumentLength = function(ideal, actual) {
|
||
|
if (ideal != actual) { throw new Error("" + ideal + " arguments needed"); }
|
||
|
}
|
||
|
Fraction.change = function(oldFrac, newFrac) {
|
||
|
Fraction.correctArgumentLength(2, arguments.length);
|
||
|
oldFrac.numerator = newFrac.numerator;
|
||
|
oldFrac.denominator = newFrac.denominator;
|
||
|
return oldFrac;
|
||
|
}
|
||
|
Fraction.isString = function(s) {
|
||
|
return typeof(s) == "string" || (typeof(s) == 'object' && s.constructor == String)
|
||
|
}
|
||
|
Fraction.fromFraction = function(frac) {
|
||
|
return typeof(frac) == 'object' && frac.constructor == Fraction;
|
||
|
}
|
||
|
Fraction.toFraction = function(x) {
|
||
|
if (!Fraction.fromFraction(x)) {
|
||
|
return new Fraction(x);
|
||
|
}
|
||
|
return x;
|
||
|
}
|
||
|
Fraction.decimalToFraction = function(x) {
|
||
|
Fraction.correctArgumentLength(1, arguments.length);
|
||
|
if (isNaN(x)) { throw new Error("Argument invalid") }
|
||
|
|
||
|
x = String(x);
|
||
|
var decLocation = x.indexOf('.');
|
||
|
if (decLocation != -1) {
|
||
|
var whole = x.substring(0, decLocation);
|
||
|
var remainder = x.substring(decLocation + 1, x.length);
|
||
|
var nthPlace = Math.pow(10, remainder.length);
|
||
|
return Fraction.add(new Fraction(Number(whole), 1), new Fraction(Number(remainder), nthPlace))
|
||
|
}
|
||
|
else { return new Fraction(Number(x)); }
|
||
|
}
|
||
|
|
||
|
if (typeof module !== "undefined" && module.exports) {
|
||
|
module.exports = Fraction;
|
||
|
}
|