diff --git a/src/Q96.ts b/src/Q96.ts new file mode 100644 index 0000000..bb02a4e --- /dev/null +++ b/src/Q96.ts @@ -0,0 +1,27 @@ +// Q64.96 helpers (JavaScript) +const Q96: bigint = 1n << 96n; + +function toQ96(x: string | number): bigint { // x: string | number -> bigint + // Use Decimal for precise parsing if needed + const [intPart, fracPart = ""] = String(x).split("."); + const frac: string = (fracPart + "0".repeat(30)).slice(0, 30); // up to 30 decimals + const scaled: bigint = BigInt(intPart) * 10n ** 30n + BigInt(frac); + return (scaled * Q96) / (10n ** 30n); +} + +function fromQ96(q: bigint): string { // q: bigint -> string + const scaled: bigint = q * (10n ** 30n) / Q96; + const intPart = scaled / (10n ** 30n); + let frac = (scaled % (10n ** 30n)).toString().padStart(30, "0"); + // trim trailing zeros + frac = frac.replace(/0+$/, ""); + return frac.length ? `${intPart.toString()}.${frac}` : intPart.toString(); +} + +function mulQ96(a: bigint, b: bigint) { // (bigint, bigint) -> bigint in Q96 + return (a * b) / Q96; +} + +function divQ96(a: bigint, b: bigint) { // (bigint, bigint) -> bigint in Q96 + return (a * Q96) / b; +}