Functional Weave
Code in Python

math.round-div-big@1.0.0

impl/typescript.ts

1,387 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 { parseBigInteger } from "./math_big_integer.ts";  ← from math.big-integer ^1.0.0 · built alongside by fune
import { type RoundingMode } from "./math_round_div.ts";  ← from math.round-div ^1.0.0 · built alongside by fune

/**
 * math.round-div, for integers too big for a JavaScript number.
 *
 * An exact product such as distance x gallon size x price per litre easily
 * passes 2^53, where `roundDiv` would silently lose digits. The rounding rules
 * are the same as math.round-div's: every mode works on the magnitude and puts
 * the sign back afterwards, so -7/2 half-up is -4.
 */
export function roundDivBig(numerator: string, denominator: string, mode: RoundingMode): string {
  const n0 = parseBigInteger(numerator);
  const d0 = parseBigInteger(denominator);
  if (d0 === 0n) {
    throw new RangeError("denominator must not be zero");
  }
  const negative = n0 < 0n !== d0 < 0n;
  const n = n0 < 0n ? -n0 : n0;
  const d = d0 < 0n ? -d0 : d0;
  let quotient = n / d;
  const remainder = n % d;
  const twice = remainder * 2n;
  switch (mode) {
    case "down":
      break;
    case "up":
      if (remainder > 0n) quotient += 1n;
      break;
    case "half-even":
      if (twice > d || (twice === d && quotient % 2n === 1n)) quotient += 1n;
      break;
    case "half-up":
      if (twice >= d) quotient += 1n;
      break;
    default:
      throw new RangeError(`unknown rounding mode "${mode}"`);
  }
  return (negative && quotient !== 0n ? -quotient : quotient).toString();
}