summaryrefslogtreecommitdiff
path: root/web/src/math/Ratio.ts
diff options
context:
space:
mode:
authorJosh Kingsley <josh@joshkingsley.me>2025-10-25 20:46:35 +0300
committerJosh Kingsley <josh@joshkingsley.me>2025-10-25 22:09:48 +0300
commit5404a95c15e176d25728bf1a319ddb9828b23625 (patch)
tree639d175e15170618d36c0b22b3c8ad7764925175 /web/src/math/Ratio.ts
parent2a4d7a7fc3b968ed8cdfd958a5e65fbe140042da (diff)
refactor(web): re-organize files
Diffstat (limited to 'web/src/math/Ratio.ts')
-rw-r--r--web/src/math/Ratio.ts61
1 files changed, 61 insertions, 0 deletions
diff --git a/web/src/math/Ratio.ts b/web/src/math/Ratio.ts
new file mode 100644
index 0000000..4973ff4
--- /dev/null
+++ b/web/src/math/Ratio.ts
@@ -0,0 +1,61 @@
+/** Serializable representation of a ratio. */
+export type RatioData = [numerator: number, denominator: number];
+
+/** Representation of a ratio for performing fractional artithmetic. */
+export default class Ratio {
+ private readonly _numerator: number;
+ private readonly _denominator: number;
+
+ get numerator(): number {
+ return this._numerator;
+ }
+
+ get denominator(): number {
+ return this._denominator;
+ }
+
+ constructor(numerator: number, denominator: number) {
+ if (!Number.isInteger(numerator) || !Number.isInteger(denominator)) {
+ throw new TypeError(
+ `Ratio must have integer parts: ${numerator} / ${denominator}`,
+ );
+ }
+
+ if (denominator === 0) {
+ throw new RangeError("Ratio demnominator cannot be zero");
+ }
+
+ this._numerator = numerator;
+ this._denominator = denominator;
+ }
+
+ multiplyRatio(other: Ratio): Ratio {
+ return new Ratio(
+ this.numerator * other.numerator,
+ this.denominator * other.denominator,
+ );
+ }
+
+ divideRatio(other: Ratio): Ratio {
+ return new Ratio(
+ this.numerator * other.denominator,
+ this.denominator * other.numerator,
+ );
+ }
+
+ toNumber(): number {
+ return this.numerator / this.denominator;
+ }
+
+ static fromInteger(n: number): Ratio {
+ return new Ratio(n, 1);
+ }
+
+ toData(): RatioData {
+ return [this.numerator, this.denominator];
+ }
+
+ static fromData(ratio: RatioData): Ratio {
+ return new Ratio(ratio[0], ratio[1]);
+ }
+}