MCPcopy Create free account
hub / github.com/cortex-js/compute-engine / fplnDirect

Function fplnDirect

src/big-decimal/utils.ts:391–429  ·  view source on GitHub ↗

* Direct-log fixed-point natural logarithm (machine-seed + log1p correction). * * ln(v) = y₀ + log1p(v·e^{−y₀} − 1), where y₀ = Math.log(v) is a ~48-bit-accurate * float64 seed. Because v·e^{−y₀} = 1 + ε with ε ≈ 2^{−48}, the correction * log1p(ε) = 2·atanh(ε/(2+ε)) needs only ≈ bits/96 series t

(x: bigint, bits: number)

Source from the content-addressed store, hash-verified

389 * @returns ln(x/2^bits) * 2^bits as a bigint.
390 */
391function fplnDirect(x: bigint, bits: number): bigint {
392 const B = BigInt(bits);
393 const scale = 1n << B;
394
395 // Overflow-safe ~48-bit float seed y₀ ≈ ln(x/scale)·scale. Extract the top
396 // ~52 bits of x so Number() stays finite even when 2^bits overflows a double
397 // (bits ≥ 1024); the log1p correction restores full precision regardless.
398 const topBits = 52;
399 const sh = bits - topBits;
400 let y0Fp: bigint;
401 if (sh > 0) {
402 const v = Number(x >> BigInt(sh)) / 2 ** topBits;
403 y0Fp = BigInt(Math.round(Math.log(v) * 2 ** topBits)) << BigInt(sh);
404 } else {
405 const v = Number(x) / Number(scale);
406 y0Fp = BigInt(Math.round(Math.log(v) * Number(scale)));
407 }
408
409 // p = x·e^{−y₀} = (1 + ε)·scale, ε ≈ 2^{−48}. The single fpexp call.
410 const p = (x * fpexp(-y0Fp, bits)) >> B;
411 const eps = p - scale; // ε·scale (may be negative if y₀ overshot ln v)
412
413 // log1p(ε) = 2·atanh(u), u = ε/(2+ε). The atanh terms all share u's sign, so
414 // sum in magnitude: an arithmetic right-shift of a negative bigint floors
415 // toward −∞ and sticks at −1 instead of reaching 0, which would never
416 // terminate the loop.
417 const u = (eps << B) / (p + scale);
418 const uAbs = u < 0n ? -u : u;
419 const u2 = (uAbs * uAbs) >> B;
420 let term = uAbs;
421 let sum = uAbs;
422 for (let n = 3n; ; n += 2n) {
423 term = (term * u2) >> B;
424 if (term === 0n) break;
425 sum += term / n;
426 }
427
428 return y0Fp + (u < 0n ? -2n : 2n) * sum;
429}
430
431/**
432 * ln(2) · 2^bits, cached. Computed once via the Newton path (NOT the AGM path,

Callers 1

fplnFunction · 0.85

Calls 3

fpexpFunction · 0.85
logMethod · 0.65
roundMethod · 0.45

Tested by

no test coverage detected