generated from raulanatol/template-ts-package
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fraction.ts
48 lines (42 loc) · 1.2 KB
/
fraction.ts
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
/*********
* This is a port of the bare minimum functionality from the 'fraction.js'
* npm package to suit the needs of dealing with fractional beat offsets.
* The original package has types written in a strange way that doesn't make
* typescript happy when in pure ESM mode.
*
* This and the original implementation are available under the MIT license.
* See: https://github.com/infusion/Fraction.js/blob/master/fraction.js
*********/
// eslint-disable-next-line jsdoc/require-jsdoc
function gcd(a: number, b: number) {
if (!a) return b;
if (!b) return a;
while (true) {
a %= b;
if (!a) return b;
b %= a;
if (!b) return a;
}
}
export class Fraction {
constructor(
public n: number,
public d: number = 1,
) {}
add(f: Fraction) {
if (f.d === this.d) {
return new Fraction(this.n + f.n, this.d);
}
return new Fraction(this.n * f.d + this.d * f.n, this.d * f.d).simplify();
}
mod(f: Fraction) {
return new Fraction((f.d * this.n) % (f.n * this.d), f.d * this.d);
}
simplify() {
const reduceBy = gcd(this.n, this.d);
return new Fraction(this.n / reduceBy, this.d / reduceBy);
}
toString() {
return (this.n / this.d).toString();
}
}