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);
}