lib/newMath.spl)
Pure SPL math: constants pi,
e, and ln2; transcendental
function.exp and function.ln (Chebyshev-fit
minimax-style Horner polynomials, no Python math.exp /
log in the interpreter); function.power uses
exponentiation by squaring when b is integral and
exp(b · ln(a)) for fractional exponents.
function.isPrime uses a built-in table for primes below 100 (lookup and trial
divisors), an LRU hash cache for repeated tests, and 6k ± 1 trial division
from 101 onward when sqrt(a) > 97.
Pure-SPL trigonometry (sin, cos,
tan, inverses, and reciprocals) uses Maclaurin / Horner series with
range reduction — no Python C math.sin /
cos (only interpreter math.sqrtR in
asin). Load with
use newMath; (extensionless import is allowed because the file starts with
reqFileExtension.setVar(false);).
use newMath; print.number(pi); print.number(function.power(2, 8)); test.assertTrue(function.isPrime(1009));
pi — double-precision π.e — Euler’s number (also used for scaling in exp).ln2 — ln(2); used when reducing ln(x) to [1,2).function.exp(x) — e^x: write
x = n + f with n = round(x) and
f ∈ [-0.5, 0.5], then e^x = e^n · e^f with a
fixed Horner polynomial for e^f. Integer scaling
e^n also uses exponentiation by squaring.
function.ln(x) — natural log for x > 0;
returns null for x ≤ 0.
function.power(a, b) — integer b:
function.powerInt (binary exponentiation, O(log b)). Negative
a uses |a|^b with a sign flip when
b is odd. Non-integer b and
a > 0: exp(b·ln(a)).
0^0 → 1; 0^negative → null;
negative a with non-integer b → null.
function.abs(a) — absolute value.function.isPrime(a) — returns 1 if
a is prime, else 0. Integer inputs are
cached (see below). Non-integers are tested without caching.
function.gcd(a, b) — Euclidean GCD (recursive).function.factorial(n) — non-negative integers only; invalid input uses
return.boolean(null).
function.lcm(a, b) — via a*b/gcd(a,b).function.isInteger(a) — true when type.isNumber
and value equals math.floor(a).
function.setPrimeCacheCap(n) — set the LRU prime-cache capacity (minimum
1); evicts oldest entries when shrinking. Returns the new cap.
function.clearPrimeCache() — empty the prime result cache.
All trig helpers are radians. Arguments are range-reduced to a small interval, then evaluated with
Horner-form Maclaurin series. Call via function.call(function.ref(sin), x)
or directly inside other newMath functions after
use newMath;.
halfPi — π/2.quarterPi — π/4.twoPi — 2π (used by range reduction).function.sin(x) — sine. Reduce to [-π, π],
fold to [-π/2, π/2]; Maclaurin on |x| ≤ π/4,
cosine complement nearer π/2.
function.cos(x) — cosine; implemented as
sin(x + π/2).
function.tan(x) — tangent (sin/cos).
Returns null when cos(x) ≈ 0.
function.reciprocal(x) — 1/x;
null at 0.
function.sec(x) — secant (1/cos(x)).function.csc(x) — cosecant (1/sin(x)).function.cot(x) — cotangent (1/tan(x)).function.asin(x) — arcsine for x ∈ [-1, 1]
via atan(x / sqrt(1 − x²)) (uses math.sqrtR).
null out of domain.
function.acos(x) — arccosine;
π/2 − asin(x) on [-1, 1].
function.atan(x) — arctangent; split at
0.5 and use π/2 − atan(1/x) for
|x| > 1.
function.acot(x) — arccotangent;
π/2 − atan(x).
function.asec(x) — arcsecant;
acos(1/x) for |x| ≥ 1.
function.acsc(x) — arccosecant;
asin(1/x) for |x| ≥ 1.
use newMath; print.number(function.call(function.ref(sin), 0)); print.number(function.call(function.ref(cos), 0)); print.number(function.call(function.ref(tan), 1)); print.number(function.call(function.ref(atan), 1)); print.number(function.call(function.ref(asin), 0.5));
function.isPrimeCompute (used internally on cache miss) applies these steps:
a < 2 → not prime.newMath_primes100Set (hash, average O(1)) —
all primes below 100. Hit → prime. The ordered list
newMath_primes100 is kept for trial division below.
a ≤ 100 but not in the table → not prime.a > 100 — first try dividing by every prime in
newMath_primes100 that is ≤ floor(sqrt(a)).
If any divide a, it is composite.
sqrt(a) > 97, continue with
6k ± 1 trial division starting at
101 / 103 up to
floor(sqrt(a)).
After use newMath;, each integer function.isPrime
call stores its result in newMath_primeCache (hash map). The next call with the same
integer returns the cached value immediately and marks that entry as most recently used.
50 entries
(newMath_primeCacheCap).
newMath_primeCacheSize — current number of cached entries (read-only usage).
use newMath; #comment: First call computes; second call hits the cache. test.assertTrue(function.isPrime(10007)); test.assertTrue(function.isPrime(10007)); #comment: Raise capacity to 100 (evicts oldest if current size > 100). function.setPrimeCacheCap(100); #comment: Or assign the variable directly (trim with setPrimeCacheCap when shrinking). newMath_primeCacheCap.setVar(75); function.clearPrimeCache();
Implementation: someProgrammingLanguage/lib/newMath.spl