Functional Weave
Code in Rust

math.pow@1.0.0

impl/typescript.ts

1,779 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 { ln } from "./math_ln.ts";  ← from math.ln ^1.0.0 · built alongside by fune
import { exp } from "./math_exp.ts";  ← from math.exp ^1.0.0 · built alongside by fune

// Below this exponent of e the result is smaller than any normal double.
const SMALLEST = -708;
const LARGEST = 709;

/**
 * base^exponent with the same bits in TypeScript, Python and Rust.
 *
 * A whole-number exponent is done by repeated squaring, so 10^3 is exactly
 * 1000 and (-2)^3 is -8, where exp(3 ln 10) would be 999.9999999999998. Any
 * other exponent is exp(exponent * ln(base)) from math.exp and math.ln, which
 * use only operations IEEE 754 defines exactly; Math.pow and ** are the
 * platform's and may differ in the last bit.
 */
export function pow(base: number, exponent: number): number {
  if (typeof base !== "number" || !Number.isFinite(base)) {
    throw new RangeError(`pow needs a finite base, received ${base}`);
  }
  if (typeof exponent !== "number" || !Number.isFinite(exponent)) {
    throw new RangeError(`pow needs a finite exponent, received ${exponent}`);
  }
  if (base === 0) {
    if (exponent < 0) throw new RangeError("zero cannot be raised to a negative power");
    return exponent === 0 ? 1 : 0;
  }
  if (Math.floor(exponent) === exponent) {
    let n = Math.abs(exponent);
    let b = base;
    let result = 1;
    while (n > 0) {
      if (n % 2 === 1) result *= b;
      n = Math.floor(n / 2);
      if (n > 0) b *= b;
    }
    if (exponent < 0) result = 1 / result;
    if (!Number.isFinite(result)) throw new RangeError("pow result is too large to represent");
    return result + 0;
  }
  if (base < 0) throw new RangeError("a negative base needs a whole-number exponent");
  const power = exponent * ln(base);
  if (power > LARGEST) throw new RangeError("pow result is too large to represent");
  if (power < SMALLEST) return 0;
  return exp(power);
}