-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfractional-arithmetic.js
158 lines (127 loc) · 3.98 KB
/
fractional-arithmetic.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/**
* fractional-arithmetic.js is a javascript library for doing fractional arithmetic
* Author: Alexandros Georgiou <[email protected]>
*
*/
var isInteger = function(i) {
return !isNaN( i ) && ( parseInt( i ) == parseFloat( i ) );
};
module.exports.isInteger = isInteger;
var gcd = function( a, b) {
a = Math.abs( a );
b = Math.abs( b );
var temp;
while ( b > 0 ) {
temp = b;
b = a % b;
a = temp;
}
return a;
};
module.exports.gcd = gcd;
var lcm = function( a, b ) {
a = Math.abs( a );
b = Math.abs( b );
return a * ( b / gcd( a, b ) );
};
module.exports.lcm = lcm;
function NotAFractionError(message) {
this.name = 'NotAFractionError';
this.message = message || 'Not a Fraction';
}
NotAFractionError.prototype = new Error();
NotAFractionError.prototype.constructor = NotAFractionError;
function Fraction( n, d ) {
if ( typeof(n) === 'undefined' )
throw new NotAFractionError( 'You must specify a fraction' );
// create without new keyword
if ( ! ( this instanceof Fraction ) ) {
return new Fraction( n, d );
}
// create from fraction
if ( n instanceof Fraction && typeof(d) === 'undefined' ) {
this.n = n.n;
this.d = n.d;
return;
}
//create from integers
if ( isInteger(n) && isInteger(d)) {
this.n = parseInt(n);
this.d = parseInt(d);
return;
}
//create from one integer
if ( isInteger(n) && typeof(d) === 'undefined') {
this.n = parseInt(n);
this.d = 1;
return;
}
if ( typeof(n) === 'number' ) {
var ns = '' + n;
var decimals = ns.length - ns.indexOf( '.' ) - 1;
this.n = parseInt( ns.replace( '.', '' ) );
this.d = Math.pow( 10, decimals );
return;
}
throw new NotAFractionError(
'Cannot instantiate Fraction(' + n + ( typeof(d) === 'undefined' ? '' : d ) + ')'
);
}
Fraction.prototype.toString = Fraction.prototype.toS = Fraction.prototype.inspect = function() {
return '(' + this.n + '/' + this.d + ')';
};
Fraction.prototype.toNumber = function () {
return this.n / this.d;
};
Fraction.prototype.toLatex = function() {
return '\\frac{' + this.n + '}{' + this.d + '}';
};
Fraction.prototype.toMathML = function() {
return '<mfrac><mn>' + this.n + '</mn><mn>' + this.d + '</mfrac>';
};
Fraction.prototype.simplify = function() {
if ( this.d < 0 ) {
this.n *= -1;
this.d *= -1;
}
var g = gcd( this.n, this.d );
return g == 1 ? this : new Fraction( this.n / g, this.d / g);
};
Fraction.prototype.inverse = function() {
return new Fraction( this.d, this.n );
};
Fraction.prototype.times = Fraction.prototype.multiply = function( n, d ) {
if ( n instanceof Fraction && typeof(d) === 'undefined' ) {
return new Fraction( this.n * n.n, this.d * n.d ).simplify();
} else if ( isInteger(n) && isInteger(d) ) {
return this.times( new Fraction( n, d ) );
}
throw new NotAFractionError('Cannot multiply ' + this + ' with n=' + n + ', d=' + d );
};
Fraction.prototype.dividedBy = Fraction.prototype.div = function( n, d ) {
if ( n instanceof Fraction && typeof(d) === 'undefined' ) {
return n.inverse().times( this );
} else if ( isInteger(n) && isInteger(d) ) {
return this.times( new Fraction( d, n ) );
}
throw new NotAFractionError('Cannot divide '+this+' by n='+n+', d='+d);
};
Fraction.prototype.plus = function( n, d ) {
if ( n instanceof Fraction && typeof(d) === 'undefined') {
var l = lcm( this.d, n.d );
return new Fraction( this.n * l / this.d + n.n * l / n.d, l );
} else if ( isInteger(n) && isInteger(d) ) {
return this.plus( new Fraction(n,d) );
}
throw new NotAFractionError( 'Cannot add ' + this + ' to n=' + n + ', d=' + d );
};
Fraction.prototype.minus = function( n, d ) {
if ( n instanceof Fraction && typeof(d) === 'undefined' ) {
var l = lcm(this.d,n.d);
return new Fraction( this.n * l / this.d - n.n * l / n.d, l);
} else if (isInteger(n) && isInteger(d)) {
return this.minus( new Fraction(n,d) );
}
throw new NotAFractionError( 'Cannot add ' + this + ' to n=' + n + ', d=' + d);
};
module.exports.Fraction = Fraction;