Functional Weave
Code in Rust

math.rational@2.0.0

impl/typescript/rational.ts

1,727 bytes · the TypeScript implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

import { gcdWide } from "./math_gcd_lcm.ts";  ← from math.gcd-lcm ^1.0.0 · built alongside by fune
import { type Rational } from "./math_rational_types.ts";

const MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);

/**
 * Reduce a wide fraction and bring it back into the exact number range. The
 * arithmetic works on bigint products, which may be past 2^53, and only the
 * reduced result has to fit.
 */
export function rationalFromWide(numerator: bigint, denominator: bigint): Rational {
  if (denominator === 0n) {
    throw new RangeError("denominator must not be zero");
  }
  const g = gcdWide(numerator, denominator);
  let n = numerator / g;
  let d = denominator / g;
  if (d < 0n) {
    n = -n;
    d = -d;
  }
  if (n > MAX_SAFE || n < -MAX_SAFE || d > MAX_SAFE) {
    throw new RangeError("rational overflow: the reduced result exceeds 2^53 - 1");
  }
  // Number(-0n) is 0, so a zero result never comes back as -0.
  return { numerator: Number(n), denominator: Number(d) };
}

/** Build a reduced fraction with a positive denominator. */
export function rational(numerator: number, denominator: number): Rational {
  if (!Number.isInteger(numerator) || !Number.isInteger(denominator)) {
    throw new TypeError("numerator and denominator must be integers");
  }
  if (!Number.isSafeInteger(numerator) || !Number.isSafeInteger(denominator)) {
    throw new RangeError("rational overflow: numerator and denominator must be within 2^53 - 1");
  }
  return rationalFromWide(BigInt(numerator), BigInt(denominator));
}

/** A checked, reduced operand as wide integers, ready to multiply without overflow. */
export function rationalParts(r: Rational): [bigint, bigint] {
  const n = rational(r.numerator, r.denominator);
  return [BigInt(n.numerator), BigInt(n.denominator)];
}