From 7699b5f9f01697a4ac3dcdaf064e11d6d7afb7b0 Mon Sep 17 00:00:00 2001 From: Marton Lederer Date: Sun, 14 Apr 2024 11:28:02 +0200 Subject: [PATCH 1/3] feat: pow refactor wip --- src/Quantity.ts | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Quantity.ts b/src/Quantity.ts index 800c23b..21e778b 100644 --- a/src/Quantity.ts +++ b/src/Quantity.ts @@ -477,16 +477,31 @@ export default class Quantity { } /** - * Raise one quantity to the power of an integer. This can cause precision loss + * Raise one quantity to the power of another. This can cause precision loss * @param x Quantity to raise * @param y Exponent * @returns Result of the power operation */ - static __pow(x: Quantity, y: number) { - if (!Number.isInteger(y)) { - throw new Error("Cannot raise Quantity to the power of a non-integer number"); + static __pow(x: Quantity, y: Quantity | bigint) { + if (typeof y !== "bigint" && !Quantity.isQuantity(y)) { + throw new Error("Invalid exponent"); } - if (y === 0) return new Quantity(0, x.#D); + + // power of 0 + if ((typeof y === "bigint" && y === 0n) || Quantity.isQuantity(y) && Quantity.eq(y, new Quantity(0n, y.#D))) { + return Quantity.__one(x.#D); + } + + // integer power + if (typeof y === "bigint") { + return new Quantity( + x.#qty ** y, + x.#D ** y + )._convert(x.#D); + } + + // ensure same denomination + [x, y] = Quantity.sameDenomination(x, y); let res = x.clone(); @@ -506,11 +521,11 @@ export default class Quantity { } /** - * Raise one quantity to the power of an integer (in-place). This can cause + * Raise one quantity to the power of another (in-place). This can cause * precision loss * @param y Exponent */ - _pow(y: number) { + _pow(y: Quantity | bigint) { const res = Quantity.__convert( Quantity.__pow(this, y), this.#D From fbe0def03816a97a216cef50191cc186c45061cb Mon Sep 17 00:00:00 2001 From: Marton Lederer Date: Sun, 14 Apr 2024 11:31:01 +0200 Subject: [PATCH 2/3] feat: negative pow wip --- src/Quantity.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Quantity.ts b/src/Quantity.ts index 21e778b..97befc7 100644 --- a/src/Quantity.ts +++ b/src/Quantity.ts @@ -494,8 +494,13 @@ export default class Quantity { // integer power if (typeof y === "bigint") { + let newRaw = x.#qty ** (y > 0 ? y : -y); + + // TODO: precision + if (y < 0) newRaw = 1n / newRaw; + return new Quantity( - x.#qty ** y, + newRaw, x.#D ** y )._convert(x.#D); } From 635b851649ff866857ab4f280d7bff9985e1c164 Mon Sep 17 00:00:00 2001 From: Marton Lederer Date: Mon, 15 Apr 2024 10:40:30 +0200 Subject: [PATCH 3/3] feat: support negative integer exponent --- src/Quantity.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Quantity.ts b/src/Quantity.ts index 97befc7..2748a85 100644 --- a/src/Quantity.ts +++ b/src/Quantity.ts @@ -494,15 +494,19 @@ export default class Quantity { // integer power if (typeof y === "bigint") { - let newRaw = x.#qty ** (y > 0 ? y : -y); - - // TODO: precision - if (y < 0) newRaw = 1n / newRaw; - - return new Quantity( - newRaw, + const positivePower = new Quantity( + x.#qty ** (y > 0 ? y : -y), x.#D ** y )._convert(x.#D); + + // negative exponent + if (y > 0) return positivePower; + + // calculate negative exponent + const result = Quantity.__one(x.#D); + result._div(positivePower); + + return result; } // ensure same denomination