Mathematics.rex
Appearance
Introduction
This year I started posting on RosettaCode and found the copy-and-paste way to get a working program annoying. Therefore I'll gather all procedures I have until now and present them here in a set libraries and stand-alone files. Other entries will link to this page.
See documentation for help and tips.
Complex
/* Complex numbers library - Build 5 Dec 2024 */
/* (C) Paul van den Eertwegh 2024 */
/* Numbers are coded as string 're im' (rectangular) */
/* Example '123 456' = '123+456i' */
Cabs:
/* Absolute value (modulus, magnitude) */
procedure expose glob.
arg xx
/* Modulus */
return Cmod(xx)
Cadd:
/* Add */
procedure
if Arg() < 2 then say argument
do n = 1 to Arg()
xx = Arg(n) 0 0; parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Sum */
if n = 1 then do
zr = xr; zi = xi
end
else do
zr = zr+xr; zi = zi+xi
end
end
return (zr) (zi)
Carg:
/* Argument (phase) */
procedure expose glob.
arg xx; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Argument between -pi and pi */
if xr = 0 & xi = 0 then
return 0
else
return Atan2(xi,xr)
Cconj:
/* Conjugate */
procedure
arg xx; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Conjugate */
return (xr) (-xi)
Ccueq:
/* Roots of cubic ax^3+bx^2+cx+d = 0 */
procedure expose cueq. glob.
arg xx; xx = xx 0 0 0 0
parse var xx a b c d .
if \ Number(a) then say argument
if \ Number(b) then say argument
if \ Number(c) then say argument
if \ Number(d) then say argument
if a = 0 then say argument
/* Method Cardano et al */
numeric digits Digits()*2
/* Reduce to x^3+ax^2+bx+c */
parse value b/a c/a d/a with a1 b1 c1
/* Reduce to x^3+ax+b */
h1 = a1*a1; h2 = h1*a1
a2 = b1-h1/3; b2 = -h2/27+h2/9-a1*b1/3+c1
/* Discriminant */
s = Round(b2*b2/4+a2*a2*a2/27,Digits()/2)
/* Roots */
cueq. = 0
select
when s < 0 then do
h1 = Abs(a2)/3
f = Acos(-b2/(2*Sqrt(h1*h1*h1)))
h1 = 2*Sqrt(h1); h2 = f/3; h3 = Pi()/3; h4 = a1/3
cueq.root.1 = h1*Cos(h2)-h4
cueq.root.2 = -h1*Cos(h2-h3)-h4
cueq.root.3 = -h1*Cos(h2+h3)-h4
end
when s = 0 then do
h1 = Curt(-b2/2); h2 = a1/3
cueq.root.1 = 2*h1-h2
cueq.root.2 = -h1-h2
cueq.root.3 = cueq.root.2
end
when s > 0 then do
h1 = b2/2
f = Sqrt((h1)**2+(a2*a2*a2/27)); g = Curt(-h1+f); h = Curt(-h1-f)
h1 = g+h; h2 = -h1/2; h3 = a1/3; h4 = Sqrt(3)*(g-h)/2
cueq.root.1 = h1-h3
cueq.root.2 = (h2-h3) (h4)
cueq.root.3 = (h2-h3) (-h4)
end
end
/* Discard roundoff digits */
do i = 1 to 3
cueq.root.i = Cround(cueq.root.i,Digits()-4)
end
numeric digits Digits()/2
/* Normalize */
do i = 1 to 3
cueq.root.i = Cnorm(cueq.root.i)
end
/* Number of roots */
cueq.0 = 3
return 3
Cdiv:
/* Divide */
procedure
if Arg() < 2 then say argument
do n = 1 to Arg()
xx = Arg(n) 0 0; parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Quotient */
if n = 1 then do
zr = xr; zi = xi
end
else do
if xr = 0 & xi = 0 then say argument
d = xr*xr+xi*xi
r = (zr*xr+zi*xi)/d; i = (zi*xr-zr*xi)/d
zr = r; zi = i
end
end
return (zr) (zi)
Cequ:
/* Equality */
procedure
arg xx,yy; xx = xx 0 0; yy = yy 0 0
parse var xx xr xi .
parse var yy yr yi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
if \ Number(yr) then say argument
if \ Number(yi) then say argument
/* Equal? */
if xr = yr & xi = yi then
return 1
else
return 0
Ceval:
/* Evaluate polynomial with real coefficients */
procedure
arg xx,yy; yy = yy 0 0
parse var yy yr yi .
if xx = '' then say argument
if \ Number(yr) then say argument
if \ Number(yi) then say argument
/* Evaluate */
zz = 0 0
numeric digits Digits()+2
do n = 1 to Words(xx)
zz = Cadd(Cmul(zz,yy),Word(xx,n))
end
numeric digits Digits()-2
/* Normalize */
return Cnorm(zz)
Cim:
/* Imaginary part */
procedure
arg xx; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Imagery part */
return (xi+0)
Cinv:
/* Invert */
procedure
arg xx
/* Inversion */
return Cdiv(1,xx)
Cmod:
/* Modulus (absolute value, magnitude) */
procedure expose glob.
arg xx; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Modulus */
return Sqrt(xr*xr+xi*xi)
Cmul:
/* Multiply */
procedure
if Arg() < 2 then say argument
do n = 1 to Arg()
xx = Arg(n) 0 0; parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Product */
if n = 1 then do
zr = xr; zi = xi
end
else do
r = zr*xr-zi*xi; i = zr*xi+zi*xr
zr = r; zi = i
end
end
return (zr) (zi)
Cneg:
/* Negate */
procedure
arg xx; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Negation */
return (-xr) (-xi)
Cnorm:
/* Normalize */
procedure
arg xx; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Round to numeric digits and trim zeroes */
return (xr/1) (xi/1)
Complex:
/* Complex? */
procedure
arg xx; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
if xi = 0 then
return 0
else
return 1
Cpol2form:
/* Polar -> formula */
procedure
arg xx; xx = xx 0 0
parse var xx xm xa .
if \ Number(xm) then say argument
if \ Number(xa) then say argument
/* Formula */
if xm = 0 then
return 0
za = xm'r'
select
when xa < 0 then
zb = '-'Abs(xa)'th'
when xa = 0 then
zb = ''
when xa > 0 then
zb = ','xa'th'
end
return za||zb
Crect:
/* Polar -> rectangular */
procedure expose glob.
arg xx; xx = xx 0 0
parse var xx xm xa .
if \ Number(xm) then say argument
if \ Number(xa) then say argument
/* Rectangular */
return (xm*Cos(xa)) (xm*Sin(xa))
Cpower:
/* Integer power */
procedure
arg xx,yy; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
/* Repeated divide or multiply */
numeric digits Digits()+2
select
when yy < 0 then do
zz = Cinv(xx)
do Abs(yy)-1
zz = Cdiv(zz,xx)
end
end
when yy = 0 then
return 1
when yy > 0 then do
zz = xx
do yy-1
zz = Cmul(zz,xx)
end
end
end
/* Normalize */
numeric digits Digits()-2
return Cnorm(zz)
Cqueq:
/* Roots of quartic ax^4+bx^3+cx^2+dx+e = 0 */
procedure expose queq. glob.
arg xx; xx = xx 0 0 0 0 0
parse var xx a b c d e .
if \ Number(a) then say argument
if \ Number(b) then say argument
if \ Number(c) then say argument
if \ Number(d) then say argument
if \ Number(e) then say argument
if a = 0 then say argument
/* Method Abramowitz and Stegun, courtesy PlanetCalc */
numeric digits Digits()*2
/* Reduce to x^4+ax^3+bx^2+cx+d */
parse value b/a c/a d/a e/a with a3 a2 a1 a0
/* Solve resolvent cubic x^3+ax^2+bx+c for real roots */
n = Cueq((1) (-a2) (a1*a3-4*a0) (4*a0*a2-a1**2-a0*a3**2))
/* Use max root */
u1 = cueq.root.1
do i = 2 to n
u1 = Max(cueq.root.i,u1)
end
/* Compute coefficients square equations */
h = Sqrt(Round(a3**2/4+u1-a2,Digits()-2)); p1 = a3/2+h; p2 = a3/2-h
h = Sqrt(Round(u1**2/4-a0,Digits()-2)); q1 = u1/2+h; q2 = u1/2-h
if Round(p1*q2+p2*q1-a1,Digits()/2) <> 0 then
parse value q2 q1 with q1 q2
/* Find roots by solving ax^2+bx+c for complex roots */
queq. = 0
call Csqeq 1 p1 q1
queq.root.1 = sqeq.root.1
queq.root.2 = sqeq.root.2
call Csqeq 1 p2 q2
queq.root.3 = sqeq.root.1
queq.root.4 = sqeq.root.2
/* Discard roundoff digits */
do i = 1 to 4
queq.root.i = Cround(queq.root.i,Digits()-4)
end
/* Normalize */
numeric digits Digits()/2
do i = 1 to 4
queq.root.i = Cnorm(queq.root.i)
end
/* Number of roots */
queq.0 = 4
return 4
Cre:
/* Real part */
procedure
arg xx; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Real part */
return xr+0
Crect2form:
/* Rectangular -> formula */
procedure
arg xx; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Formula */
if xr = 0 then
za = ''
else
za = xr
select
when xi < 0 then
if xi = -1 then
zb = '-i'
else
zb = xi'i'
when xi = 0 then
if xr = 0 then
zb = 0
else
zb = ''
when xi > 0 then
if xi = 1 then
zb = '+i'
else
zb = '+'xi'i'
end
return za||zb
Cpol:
/* Rectangular -> polar */
procedure expose glob.
arg xx
/* Polar */
return (Cmod(xx)) (Carg(xx))
Cround:
/* Round to specified decimals */
procedure
arg xx,yy; xx = xx 0 0
parse var xx xr xi .
if yy = '' then
yy = Digits()
if \ Number(xr) then say argument
if \ Number(xi) then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
/* Round */
return (Round(xr,yy)) (Round(xi,yy))
Cscale:
/* Scale */
procedure
arg xx,yy; yy = yy 0 0
parse var yy yr yi .
if \ Number(xx) then say argument
if \ Number(yr) then say argument
if \ Number(yi) then say argument
/* Multiply by constant */
return (xx*yr) (xx*yi)
Csci:
/* Convert to scientific format */
procedure
arg xx; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Force format */
return (Format(xr,,,,0)) (Format(xi,,,,0))
Csqeq:
/* Roots of square ax^2+bx+c = 0 */
procedure expose sqeq. glob.
arg xx; xx = xx 0 0 0
parse var xx a b c .
if \ Number(a) then say argument
if \ Number(b) then say argument
if \ Number(c) then say argument
if a = 0 then say argument
/* Abc formula */
numeric digits Digits()+5
/* Discriminant */
s = Round(b*b-4*a*c,Digits()-3)
/* Roots */
sqeq. = 0; h1 = -1/(2*a)
select
when s < 0 then do
h2 = Sqrt(-s)
sqeq.root.1 = (h1*b) (h1*h2)
sqeq.root.2 = (h1*b) (-h1*h2)
end
when s = 0 then do
sqeq.root.1 = h1*b
sqeq.root.2 = sqeq.root.1
end
when s > 0 then do
h2 = Sqrt(s)
sqeq.root.1 = h1*(b+h2)
sqeq.root.2 = h1*(b-h2)
end
end
/* Discard roundoff digits */
do i = 1 to 2
sqeq.root.i = Cround(sqeq.root.i,Digits()-3)
end
numeric digits Digits()-5
/* Normalize */
do i = 1 to 2
sqeq.root.i = Cnorm(sqeq.root.i)
end
/* Number of roots */
sqeq.0 = 2
return 2
Csqrt:
/* Square root */
procedure expose glob.
arg xx; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Principal value */
numeric digits Digits()+2
m = Cmod(xx)
if xi < 0 then
s = -1
else
s = 1
a = Round(m+xr,Digits()-2); b = Round(m-xr,Digits()-2)
r = Sqrt(a/2); i = Sqrt(b/2)*s
numeric digits Digits()-2
return (r/1) (i/1)
Cstd:
/* Convert to standard format */
procedure
arg xx; xx = xx 0 0
parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Force format */
return (Format(xr,,,0)) (Format(xi,,,0))
Csub:
/* Subtract */
procedure
if Arg() < 2 then say argument
do n = 1 to Arg()
xx = Arg(n) 0 0; parse var xx xr xi .
if \ Number(xr) then say argument
if \ Number(xi) then say argument
/* Difference */
if n = 1 then do
zr = xr; zi = xi
end
else do
zr = zr-xr; zi = zi-xi
end
end
return (zr) (zi)
Constants
/* Constants library - Build 5 Dec 2024 */
/* (C) Paul van den Eertwegh 2023-2024 */
Apery:
/* Apery constant */
procedure
if Digits() < 101 then
/* Fast value */
zz = 1.20205690315959428539973816151144999076498629234049888179227155534183820578631309018645587360933526
else do
/* Wedeniwski recurring */
numeric digits Digits()+2
numeric fuzz 2
/* Term k = 0 */
f10 = 1; f20 = 1; f21 = 1; f32 = 2; f43 = 6; p = 12463; s = 1
zz = 0; v = 0
do k = 1
/* Add term */
zz = zz+s*((f10*f20*f21)**3*p)/(f32*f43**3)
if zz = v then
leave
v = zz
/* Prepare next term */
k2 = k+k; k3 = k2+k; k4 = k3+k
/* Factorials */
f10 = f10*k; f20 = f20*k2*(k2-1); f21 = f21*k2*(k2+1); f32 = f32*k3*(k3+1)*(k3+2); f43 = f43*k4*(k4+1)*(k4+2)*(k4+3)
/* Polynomial */
p = ((((126392*k+412708)*k+531578)*k+336367)*k+104000)*k+12463
/* Sign */
s = -s
end
zz = zz/24
numeric digits Digits()-2
end
return zz/1
Artin:
/* Artin constant */
procedure
/* Fast value */
zz = 0.373955813619202288054728054346416415111629248606150042094742802417350182040028082344304317087250568981603
return zz/1
Backhouse:
/* Backhouse constant */
procedure
/* Fast value */
zz = 1.45607494858268967139959535111654355765317837484713154027070243741400150626538989559964531940186030910992
return zz/1
Bernstein:
/* Bernstein constant */
procedure
/* Fast value */
zz = 0.28016949902386913303643649123067200004248213981236
return zz/1
Bloch:
/* Bloch constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.471861653452681784874468793611316149077012621739443243631460266888006805241859656902448655624594840993
else do
/* Formula */
numeric digits Digits()+1
zz = Sqrt((Sqrt(3)-1)*0.5)*Gamma(1/3)*Gamma(11/12)/Gamma(0.25)
numeric digits Digits()-1
end
return zz/1
Bronze:
/* Bronze ratio constant = positive root of x^2-3x-1 */
procedure
if Digits() < 101 then
/* Fast value */
zz = 3.302775637731994646559610633735247973125648286922623106355226528113583474146505222602309541009245359
else
/* Formula */
zz = 0.5*(3+Sqrt(13))
return zz/1
Brun:
/* Brun constant */
procedure
/* Fast value */
zz = 1.902160583104
return zz/1
Cahen:
/* Cahen constant */
procedure
if Digits() < 101 then
/* Fast value */
zz = 0.6434105462883380261822543077575647632865878602682395059870309203074927764618326108484408955504634320
else do
numeric digits Digits()+2
/* Sylvester */
zz = 0; v = 0; s = 2
do n = 0
zz = zz+(-1)**n/(s-1)
if zz = v
then leave
v = zz; s = s*s-s+1
end
numeric digits Digits()-2
end
return zz/1
Capacity:
/* Logarithmic capacity of the unit disk constant */
procedure
/* Fast value */
zz = 0.5901702995080481130226689702792442936168583174407236497579321997021520903603578974892293080979039771
return zz/1
Catalan1:
/* Catalan constant */
procedure
if Digits() < 101 then
/* Fast value */
zz = 0.9159655941772190150546035149323841107741493742816721342664981196217630197762547694793565129261151062
else do
numeric digits Digits()+2
numeric fuzz 2
/* Broadhurst */
s1 = 0; v = 0
do n = 0 until s1 = v
v = s1
a = 1/2**(4*n); b = 8*n
c1 = (b+1)*(b+1); c2 = (b+2)*(b+2); c3 = (b+3)*(b+3); c5 = (b+5)*(b+5); c6 = (b+6)*(b+6); c7 = (b+7)*(b+7)
s1 = s1+a*(1/(2*c1)-1/(2*c2)+1/(4*c3)-1/(8*c5)+1/(8*c6)-1/(16*c7))
end
s2 = 0; v = 0
do n = 0 until s2 = v
v = s2
a = 1/2**(12*n); b = 8*n
c1 = (b+1)*(b+1); c2 = (b+2)*(b+2); c3 = (b+3)*(b+3); c5 = (b+5)*(b+5); c6 = (b+6)*(b+6); c7 = (b+7)*(b+7)
s2 = s2+a*(1/(8*c1)+1/(16*c2)+1/(64*c3)-1/(512*c5)-1/(1024*c6)-1/(4096*c7))
end
zz = 3*s1-2*s2
numeric digits Digits()-2
end
return zz/1
Chaitin:
/* Chaitin constant */
procedure
/* Fast value */
zz = 0.0078749969978123844
return zz/1
Champernowne:
/* Champernowne constant */
procedure
if Digits() < 101 then
/* Fast value */
zz = 0.12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565
else do
p = Digits()+4
/* Concatenate integers */
zz = '0.'
do n = 1 while Length(zz) <= p
zz = zz||n
end
end
return zz/1
Conway2:
/* Conway constant = real root of x^71-x^69-2x^68...-6x^2+3x-6 */
procedure
/* Fast value or first guess */
zz = 1.30357726903429639125709911215255189073070250465940487575486139062855088785246155712681576686442522555
if Digits() > 100 then do
/* Newton */
numeric digits Digits()+3
numeric fuzz 3
do until zz = v
v = zz
/* Powers */
y2 = zz*zz; y3 = zz*y2; y4 = zz*y3; y5 = zz*y4; y6 = zz*y5; y7 = zz*y6; y8 = zz*y7; y9 = zz*y8
y10 = zz*y9; y11 = zz*y10; y12 = zz*y11; y13 = zz*y12; y14 = zz*y13; y15 = zz*y14; y16 = zz*y15; y17 = zz*y16; y18 = zz*y17; y19 = zz*y18
y20 = zz*y19; y21 = zz*y20; y22 = zz*y21; y23 = zz*y22; y24 = zz*y23; y25 = zz*y24; y26 = zz*y25; y27 = zz*y26; y28 = zz*y27; y29 = zz*y28
y30 = zz*y29; y31 = zz*y30; y32 = zz*y31; y33 = zz*y32; y34 = zz*y33; y35 = zz*y34; y36 = zz*y35; y37 = zz*y36; y38 = zz*y37; y39 = zz*y38
y40 = zz*y39; y41 = zz*y40; y42 = zz*y41; y43 = zz*y42; y44 = zz*y43; y45 = zz*y44; y46 = zz*y45; y47 = zz*y46; y48 = zz*y47; y49 = zz*y48
y50 = zz*y49; y51 = zz*y50; y52 = zz*y51; y53 = zz*y52; y54 = zz*y53; y55 = zz*y54; y56 = zz*y55; y57 = zz*y56; y58 = zz*y57; y59 = zz*y58
y60 = zz*y59; y61 = zz*y60; y62 = zz*y61; y63 = zz*y62; y64 = zz*y63; y65 = zz*y64; y66 = zz*y65; y67 = zz*y66; y68 = zz*y67; y69 = zz*y68
y70 = zz*y69; y71 = zz*y70
/* Polynomial and derivative */
f = y71-y69-2*y68-y67+2*y66+2*y65+y64-y63-y62-y61-y60,
-y59+2*y58+5*y57+3*y56-2*y55-10*y54-3*y53-2*y52+6*y51+6*y50,
+y49+9*y48-3*y47-7*y46-8*y45-8*y44+10*y43+6*y42+8*y41-5*y40,
-12*y39+7*y38-7*y37+7*y36+y35-3*y34+10*y33+y32-6*y31-2*y30,
-10*y29-3*y28+2*y27+9*y26-3*y25+14*y24-8*y23-7*y21+9*y20,
+3*y19-4*y18-10*y17-7*y16+12*y15+7*y14+2*y13-12*y12-4*y11-2*y10,
+5*y9+y7-7*y6+7*y5-4*y4+12*y3-6*y2+3*zz-6
f1 = 71*y70-69*y68-136*y67-67*y66+132*y65+130*y64+64*y63-63*y62-62*y61-61*y60-60*y59,
-59*y58+116*y57+285*y56+168*y55-110*y54-540*y53-159*y52-104*y51+306*y50+300*y49,
+49*y48+432*y47-141*y46-322*y45-360*y44-352*y43+430*y42+252*y41+328*y40-200*y39,
-468*y38+266*y37-259*y36+252*y35+35*y34-102*y33+330*y32+ 32*y31-186*y30-60*y29,
-290*y28-84*y27+54*y26+234*y25-75*y24+336*y23-184*y22-147*y20+180*y19,
+57*y18-72*y17-170*y16-112*y15+170*y14+98*y13+ 26*y12-144*y11-44*y10-20*y9,
+45*y8+7*y6-42*y5+35*y4-16*y3+36*y2-12*zz+3
/* Next value */
zz = zz-f/f1
end
numeric digits Digits()-3
end
return zz/1
Copeland:
/* Copeland-Erdos constant */
procedure
/* Fast value */
zz = 0.23571113171923293137414347535961677173798389971011031071091131271311371391491511571631671731791811911
return zz/1
Devicci:
/* DeVicci constant = positive root of 4x^8-28x^6-7x^4+16x^2+16 */
procedure
/* Fast value or first guess */
zz = 1.007434756884279376098253595231099141925690114113669770234963798571152313280286777962520551474635923942
if Digits() > 100 then do
/* Newton */
numeric digits Digits()+2
numeric fuzz 2
zz = 1.007434756884279376098253595231099141925690114113669770234963798571152313280286777962520551474635923942
do until zz = v
v = zz
/* Powers */
y2 = zz*zz; y3 = y2*zz; y4 = y3*zz; y5 = y4*zz; y6 = y5*zz; y7 = y6*zz; y8 = y7*zz
/* Polynomial and derivatives */
f = 4*y8-28*y6-7*y4+16*y2+16
f1 = 32*y7-168*y5-28*y3+32*zz
/* Next value */
zz = zz-f/f1
end
numeric digits Digits()-2
end
return zz/1
Dottie:
/* Dottie constant = root of Cos(x) - x */
procedure expose glob.
/* Fast value or first guess */
zz = 0.7390851332151606416553120876738734040134117589007574649656806357732846548835475945993761069317665318
if Digits() > 100 then do
numeric digits Digits()+2
/* Halley */
do until zz = v
numeric fuzz
v = zz
c = Cos(zz); s = Sin(zz); f = c-zz; f1 = -s-1; f2 = -c
zz = zz - (2*f*f1) / (2*f1*f1-f*f2)
numeric fuzz 2
end
numeric fuzz
numeric digits Digits()-2
end
return zz/1
Dubois:
/* Second Dubois-Reymond constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.194528049465325113615213730287503906590157785275923662043563911261286898039528881692156242539560897386876
else
/* Formula */
zz = (E()**2-7)*0.5
return zz/1
E:
/* Euler constant */
procedure expose glob.
p = Digits()
/* In memory? */
if glob.e.p <> '' then
return glob.e.p
if p < 101 then
/* Fast value */
glob.e.p = 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516643+0
else do
numeric digits Digits()+2
numeric fuzz 2
/* Taylor */
zz = 2; t = 1; v = zz
do n = 2 until zz = v
v = zz
t = t/n; zz = zz+t
end
numeric digits Digits()-2
glob.e.p = zz+0
end
return glob.e.p
Embree:
/* Embree-Trefethen constant */
procedure
/* Fast value */
zz = 0.70258
return zz/1
Erdos1:
/* Erdos-Borwein constant */
procedure
if Digits() < 101 then
/* Fast value */
zz = 1.606695152415291763783301523190924580480579671505756435778079553691418420743486690565711801670155575897045429
else do
numeric digits Digits()+2
numeric fuzz 2
/* Series */
zz = 0; v = 0
do n = 1 until zz = v
v = zz
a = 2**n; zz = zz+(1/a**n)*(a+1)/(a-1)
end
numeric digits Digits()-2
end
return zz/1
Erdos2:
/* Erdos-Tenenbaum-Ford constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.08607133205593420688757309877692267776059110953033317349202023666542263581462287979938053460252876807163
else
/* Formula */
zz = 1-(1+Ln(Ln(2)))/Ln(2)
return zz/1
Euler:
/* Euler-Mascheroni constant */
procedure expose glob.
p = Digits()
/* In memory? */
if glob.euler.p <> '' then
return glob.euler.p
if p < 101 then
/* Fast value */
glob.euler.p = 0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495+0
else do
numeric digits Digits()+2
/* Brent McMillan */
n = Ceil((Digits()*Ln(10)+Ln(Pi()))*0.25); m = Ceil(2.07*Digits())
n2 = n*n; ak = -Ln(n); bk = 1; s = ak; v = 1
do k = 1 to m
bk = bk*n2/(k*k); ak = (ak*n2/k+bk)/k
s = s+ak; v = v+bk
end
numeric digits Digits()-2
glob.euler.p = s/v
end
return glob.euler.p
Feigenbaum1:
/* Feigenbaum first constant */
procedure
/* Fast value */
zz = 4.66920160910299067185320382046620161725818557747576863274565134300413433021131473713868974402394801381716
return zz/1
Feigenbaum2:
/* Feigenbaum second constant */
procedure
/* Fast value */
zz = 2.50290787509589282228390287321821578638127137672714997733619205677923546317959020670329964974643383412959
return zz/1
Feller:
/* Feller-Tornier constant */
procedure
/* Fast value */
zz = 0.66131704946962233528976584627411853328547528983291635498090562622662503174312230494226174078428187
return zz/1
Foias:
/* Foias constant */
procedure
/* Fast value */
zz = 1.18745235112650105459548015839651935121569268158586035301010412619878041872352540738702465760608657943378
return zz/1
Fraction:
/* First continued fraction constant */
procedure
/* Fast value */
zz = 0.697774657964007982006790592551752599486658262998021232368630082816530852764641112996965654182676568723982
return zz/1
Fransen:
/* Fransen-Robertson constant */
procedure
/* Fast value */
zz = 2.80777024202851936522150118655777293230808592093019829122005480959710088912190166551018530816819663814187
return zz/1
Gauss:
/* Gauss constant */
procedure
if Digits() < 101 then
/* Fast value */
zz = 0.8346268416740731862814297327990468089939930134903470024498273701036819927095264118696911603512753241
else
/* Formula */
zz = 1/Agmean(1,Sqrt(2))
return zz/1
Gelfond1:
/* Gelfond constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 23.1406926327792690057290863679485473802661062426002119934450464095243423506904527835169719970675492
else
/* Formula */
zz = Pow(E(),Pi())
return zz/1
Gelfond2:
/* Gelfond-Schneider constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 2.66514414269022518865029724987313984827421131371465949283597959336492044617870595486760918000519642
else
/* Formula */
zz = Pow(2,Sqrt(2))
return zz/1
Gieseking:
/* Gieseking constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 1.01494160640965362502120255427452028594168930753029979201748910677659747625824402213647035422825669
else
/* Formula */
zz = (Trigamma(1/3)-Trigamma(2/3))/(4*Sqrt(3))
return zz/1
Glaisher:
/* Glaisher-Kinkelin constant */
procedure
/* Fast value */
zz = 1.28242712910062263687534256886979172776768892732500119206374002174040630885882646112973649195820237
return zz/1
Golden:
/* Golden ratio constant = root of x^2-x-1 */
procedure
if Digits() < 101 then
/* Fast value */
zz = 1.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939114
else
/* Formula */
zz = (Sqrt(5)+1)*0.5
return zz/1
Goldenangle:
/* Golden angle constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 2.39996322972865332223155550663361385312499901105811504293511275073130733823943879077996206066058396
else
/* Formula */
zz = Pi()*(3-Sqrt(5))
return zz/1
Golomb1:
/* Golomb constant */
procedure
/* Fast value */
zz = 0.624329988543550870992936383100837244179642620180529286973551902495638088855113254462460276195539868869
return zz/1
Gompertz:
/* Gompertz constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.596347362323194074341078499369279376074177860152548781573484910482327219114874417470430497093612760344237
else do
numeric digits Digits()+2
/* Taylor */
zz = 0; s = 1; f = 1
do n = 1 until zz = v
numeric fuzz
v = zz
s = -s; f = f*n; zz = zz+s/(n*f)
numeric fuzz 2
end
numeric fuzz
zz = -E()*(Euler()+zz)
numeric digits Digits()-2
end
return zz/1
Hafner:
/* Hafner-Sarnak-McCurley constant */
procedure
/* Fast value */
zz = 0.353236371854995984543516550432682011280164778566690446416085942814238325002669003483672078334335498967
return zz/1
Heath:
/* Heath-Brown-Moroz constant */
procedure
/* Fast value */
zz = 0.00131764115485317810981735232251358595125073432329525167879254742178602344409610895090834
return zz/1
Hermite:
/* Second Hermite constant */
procedure
if Digits() < 101 then
/* Fast value */
zz = 1.15470053837925152901829756100391491129520350254025375203720465296795534460586669138743079117149905
else
/* Formula */
zz = 2/Sqrt(3)
return zz/1
Kepler:
/* Kepler-Bouwkamp constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.1149420448532962007010401574695987428307953372008635168440233965189660128253530511779407724849858370
else do
/* Many extra digits */
numeric digits Digits()*3
/* Asymptotic */
zz = 0; v = 0
do k = 1 to 100 until zz = v
v = zz
a = 2*k; b = Zeta(a); c = 2**a
zz = zz+((c-1)/a)*b*(b-1-1/c)
end
zz = Exp(-2*zz)
numeric digits Digits()/3
end
return zz/1
Khinchin:
/* Khinchin constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 2.685452001065306445309714835481795693820382293994462953051152345557218859537152002801141174931847698
else do
numeric digits Digits()+2
/* Asymptotic */
y1 = 0; v = 0
do n = 1 until y1 = v
numeric fuzz
v = y1
y2 = 0
do k = 1 to 2*n-1
y2 = y2+(-1)**(k+1)/k
end
y1 = y1+((Zeta(2*n)-1)/n)*y2
numeric fuzz 2
end
numeric fuzz
zz = Exp(y1/Ln(2))
numeric digits Digits()-2
end
return zz/1
Komornik:
/* Komornik-Loreti constant */
procedure
/* Fast value */
zz = 1.78723165018296593301327489033700838533793140296181099778478147050555749175060568699131001863407533302
return zz/1
Landau1:
/* Landau-Ramanujan constant */
procedure
/* Fast value */
zz = 0.7642236535892206629906987312500923281167905413934095147216866737496146416587328588384015050131312337
return zz/1
Landau2:
/* Landau constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.54325896534297670695272829530061323113886329375835698895573256910043468701530783731285212710225971085753+0
else
/* Formula */
zz = Pow(2,5/3)*Pi()**2/(3*Gamma(1/3)**3)
return zz/1
Laplace:
/* Laplace limit constant */
procedure
/* Fast value */
zz = 0.66274341934918158097474209710925290705623354911502241752039253499097185308651127724965480259895818168
return zz/1
Lebesgue2:
/* Lebesgue constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.9894312738311469517416488090188667149242014060911110482841224326443725315845786546346329831401895579
else do
numeric digits Digits()+2
/* Series */
zz = 0; v = 0
do n = 0 until zz = v
numeric fuzz
v = zz
zz = zz+(Lambda1(2*n+2)-1)/(2*n+1)
numeric fuzz 2
end
numeric fuzz
a = Pi()**2
zz = 8*zz/a+4*(2*Ln(2)+Euler())/a
numeric digits Digits()-2
end
return zz/1
Lemniscate:
/* Lemniscate constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 2.6220575542921198104648395898911194136827549514316231628168217038007905870704142502302955329614291
else
/* Formula */
zz = Pi()/Agmean(1,Sqrt(2))
return zz/1
Levy1:
/* Levy-Khinchin constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 1.18656911041562545282172297594723712056835653647205433595425429865280963205625444330034830110848687594663
else
/* Formula */
zz = Pi()**2/(12*Ln(2))
return zz/1
Levy2:
/* Second Levy constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 3.27582291872181115978768188245384386360847552598237414940519892419072321564496035518127754047917452949269
else
/* Formula */
zz = Exp(Levy1())
return zz/1
Lieb:
/* Lieb constant */
procedure
if Digits() < 101 then
zz = 1.53960071783900203869106341467188654839360467005367166938293953729060712614115558851657438822866540060055
/* Fast value */
else
/* Formula */
zz = 8/(3*Sqrt(3))
return zz/1
Ln2:
/* Natural log of 2 constant */
procedure
/* Fast value */
zz = 0.6931471805599453094172321214581765680755001343602552541206800094933936219696947156058633269964186875
return zz/1
Ln4:
/* Natural log of 4 constant */
procedure
/* Fast value */
zz = 1.386294361119890618834464242916353136151000268720510508241360018986787243939389431211726653992837375
return zz/1
Ln8:
/* Natural log of 8 constant */
procedure
/* Fast value */
zz = 2.079441541679835928251696364374529704226500403080765762362040028480180865909084146817589980989256063
return zz/1
Ln10:
/* Natural log of 10 constant */
procedure
/* Fast value */
zz = 2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959830
return zz/1
Loch:
/* Loch constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.97027011439203392574025601921001083378128470478516128661035052993125419989173704803621267490802902646924
else
/* Formula */
zz = 6*Ln(2)*Ln(10)/Pi()**2
return zz/1
Magicangle:
/* Magic angle constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.9553166181245092781638571025157577542434146950100054909596981293219120459039764553873916025856280734
else
/* Formula */
zz = Acos(1/Sqrt(3))
return zz/1
Meissel:
/* Meissel-Mertens constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.261497212847642783755426838608695859051566648261199206192064213924924510897368209714142631434246651051617
else do
numeric digits Digits()+2
zz = 0; v = 0
do n = 2 to 1000
t = Moebius(n)*Ln(Zeta(n))/n
if t <> 0 then do
zz = zz+t
if zz = v then
leave
v = zz
end
end
zz = Euler()+zz
numeric digits Digits()-2
end
return zz/1
Mills:
/* Mills constant */
procedure
/* Fast value */
zz = 1.30637788386308069046861449260260571291678458515671364436805375996643405376682659882150140370119739570729
return zz/1
Mrb:
/* MRB constant */
procedure
/* Fast value */
zz = 0.187859642462067120248517934054273230055903094900138786172004684089477231564660213703296654433107496903842
return zz/1
Nielsen:
/* Nielsen-Ramanujan constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.82246703342411321823620758332301259460947495060339921886777911468500373520160043691681445030987935
else
/* Formula */
zz = Pi()**2/12
return zz/1
Niven:
/* Niven constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 1.70521114010536776428855145343450816076202765165346909999428490654731319216812249193424413210087100179
else do
numeric digits Digits()+2
/* Series */
zz = 0; v = 0
do k = 2 to 100 until zz = v
numeric fuzz
v = zz
zz = zz+1-1/Zeta(k)
numeric fuzz 2
end
numeric fuzz
zz = zz+1
numeric digits Digits()-2
end
return zz/1
Omega:
/* Omega constant = LambertW0(1) = root of x*e^x-1 */
procedure expose glob.
/* Fast value or first guess */
zz = 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946
if Digits() > 100 then do
numeric digits Digits()+3
/* Halley */
do until zz = v
numeric fuzz
v = zz
a = Exp(zz); b = a*zz-1
zz = zz-b/(a*(zz+1)-((zz+2)*b/(2*zz+2)))
numeric fuzz 3
end
numeric fuzz
numeric digits Digits()-3
end
return zz/1
Paperfolding:
/* Paper folding constant */
procedure
if Digits() < 101 then
/* Fast value */
zz = 0.850736188201867260367797760532066604411399493082710647728168261031830158459319445348545982642193923996091
else do
numeric digits Digits()+2
numeric fuzz 2
/* Definition */
zz = 0; v = 0
do n = 0 until zz = v
v = zz
zz = zz+8**(2**n)/(2**(2**(n+2))-1)
end
numeric fuzz
numeric digits Digits()-2
end
return zz/1
Parabolic:
/* Universal parabolic constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 2.29558714939263807403429804918949038759783220363858348392997534664410966268413312668409442623789762
else do
/* Formula */
a = Sqrt(2); zz = Ln(a+1)+a
end
return zz/1
Pi:
/* Pi constant */
procedure expose glob.
p = Digits()
/* In memory? */
if glob.pi.p <> '' then
return glob.pi.p
if p < 101 then
/* Fast value */
glob.pi.p = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211707+0
else do
numeric digits Digits()+2
if p < 201 then do
/* Chudnovsky */
zz = 0
do n = 0 until zz = v
numeric fuzz
v = zz; zz = zz + Fact(6*n)*(13591409+545140134*n)/(Fact(3*n)*Fact(n)**3*-640320**(3*n))
numeric fuzz 2
end
numeric fuzz
zz = 4270934400/(Sqrt(10005)*zz)
end
else do
/* Agmean */
zz = 0.25; a = 1; g = Sqrt(0.5); n = 1
do until a = v
numeric fuzz
v = a
x = (a+g)*0.5; g = Sqrt(a*g)
zz = zz-n*(x-a)**2; n = n+n; a = x
numeric fuzz 2
end
numeric fuzz
zz = a*a/zz
end
numeric digits Digits()-2
glob.pi.p = zz+0
end
return glob.pi.p
Plastic:
/* Plastic ratio constant = real root of x^3-x-1 */
procedure
if Digits() < 101 then
/* Fast value */
zz = 1.32471795724474602596090885447809734073440405690173336453401505030282785124554759405469934798178728
else do
/* Formula */
a = Sqrt(69)/18; zz = Curt(0.5+a)+Curt(0.5-a)
end
return zz/1
Porter:
/* Porter constant */
procedure
/* Fast value */
zz = 1.46707807943397547289779848470722995344990332241488777739968581761660674432904480843036932751117401521266
return zz/1
Prouhet:
/* Prouhet-Thue-Morse constant */
procedure
if Digits() < 101 then
/* Fast value */
zz = 0.4124540336401075977833613682584552830894783744557695575733794153487935923657825889638045404862121334
else do
numeric digits Digits()+2
/* Infinite product */
zz = 1; v = 0
do n = 0
zz = zz*(1-1/2**(2**n))
if zz = v
then leave
v = zz
end
zz = (2-zz)*0.25
numeric digits Digits()-2
end
return zz/1
Ramanujan:
/* Ramanujan constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 262537412640768743.999999999999250072597198185688879353856337336990862707537410378210647910118607313
else
/* Formula */
zz = Exp(Pi()*Sqrt(163))
return zz/1
Recifibo:
/* Reciprocal Fibonacci constant */
procedure
if Digits() < 101 then
/* Fast value */
zz = 3.35988566624317755317201130291892717968890513373196848649555381532513031899668338361541621645679008729704
else do
numeric digits Digits()+2
numeric fuzz 2
/* Recurring */
zz = 1; v = 0; a = 0; b = 1
do n = 2 until zz = v
v = zz
c = a+b; zz = zz+1/c
a = b; b = c
end
numeric digits Digits()-2
end
return zz/1
Robbins:
/* Robbins constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.661707182267176235155831133248413581746400135790953604808944229479584646138597631306652480768107120151709
else
/* Formula */
zz = (4+17*Sqrt(2)-6*Sqrt(3)-7*Pi())/105+(Ln(1+Sqrt(2)))*0.2+(Ln(2+Sqrt(3)))*0.4
return zz/1
Salem:
/* Salem constant = largest positive root of x^10+x^9-x^7-x^6-x^5-x^4-x^3+x+1 */
procedure
/* Fast value or first guess */
zz = 1.176280818259917506544070338474035050693415806564695259830106347029688376548549962096830115581815395
if Digits() > 100 then do
/* Newton */
numeric digits Digits()+2; numeric fuzz 2
do until zz = v
v = zz
/* Powers */
y2 = zz*zz; y3 = y2*zz; y4 = y3*zz; y5 = y4*zz; y6 = y5*zz; y7 = y6*zz; y8 = y7*zz; y9 = y8*zz; y10 = y9*zz
/* Polynomial and derivative */
f = y10+y9-y7-y6-y5-y4-y3+zz+1
f1 = 10*y9+9*y8-7*y6-6*y5-5*y4-4*y3-3*y2+1
/* Next value */
zz = zz-f/f1
end
numeric digits Digits()-2
end
return zz/1
Sierpinski:
/* Sierpinski constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 2.584981759579253217065893587383171160088051651852630917321544987971932044001157120211117724527064
else
/* Formula */
zz = Pi()*Ln(Exp(2*Euler())/(2*Gauss()**2))
return zz/1
Silver:
/* Silver ratio constant = positive root of x^2-2x-1 */
procedure
if Digits() < 101 then
/* Fast value */
zz = 2.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157
else
/* Formula */
zz = Sqrt(2)+1
return zz/1
Soldner:
/* Soldner constant */
procedure
/* Fast value */
zz = 1.45136923488338105028396848589202744949303228364801586309300455766242559575451783565953135771108682884
return zz/1
Somos:
/* Somos quadratic recurrence constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 1.66168794963359412129581892274995074996441863502506820818971116802560902982638372790836917641146116715528
else do
numeric digits Digits()+2
/* Definition */
zz = 1; v = 0; a = 2
do n = 1
zz = zz*Pow(n,1/a)
if zz = v
then leave
v = zz; a = 2*a
end
numeric digits Digits()-2
end
return zz/1
Sqrt2:
/* Square root of 2 constant */
procedure
/* Fast value */
zz = 1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573
return zz/1
Sqrt3:
/* Square root of 3 constant */
procedure
/* Fast value */
zz = 1.732050807568877293527446341505872366942805253810380628055806979451933016908800037081146186757248576
return zz/1
Sqrt5:
/* Square root of 5 constant */
procedure
/* Fast value */
zz = 2.236067977499789696409173668731276235440618359611525724270897245410520925637804899414414408378782275
return zz/1
Stephens:
/* Stephens constant */
procedure
/* Fast value */
zz = 0.57595996889294543964316337549249669250651396717649236360064079866537255169886852843640987209172618
return zz/1
Supergolden:
/* Super golden ratio constant = real solution of x^3-x^2-1 */
procedure
if Digits() < 101 then
/* Fast value */
zz = 1.46557123187676802665673122521993910802557756847228570164318311124926299668501784047812580119490927
else do
/* Formula */
a = 3*Sqrt(93); zz = (1+Curt((29+a)*0.5)+Curt((29-a)*0.5))/3
end
return zz/1
Taniguchi:
/* Taniguchi constant */
procedure
/* Fast value */
zz = 0.678234491917391978035538279482894814096332239189440103036460415964983370740123233213762122933484616888328
return zz/1
Tau1:
/* Tau constant = 2*pi */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 6.28318530717958647692528676655900576839433879875021164194988918461563281257241799725606965068423414
else
/* Formula */
zz = 2*Pi()
return zz/1
Tetranacci2:
/* Tetranacci constant = root of x^4-x^3-x^2-x-1 */
procedure
if Digits() < 101 then
/* Fast value */
zz = 1.92756197548292530426190586173662216869855425516338472714664703800966606229781555914981825346189065325
else do
/* Formula */
a = Curt((Sqrt(177304464)+7020)); zz = 1/4+Sqrt(11/48-a/72+7/a)+Sqrt(11/24+a/72-7/a+1/Sqrt(704/507-128*a/1521+7168/(169*a)))
end
return zz/1
Tribonacci2:
/* Tribonacci constant = root of x^3-x^2-x-1 */
procedure
if Digits() < 101 then
/* Fast value */
zz = 1.839286755214161132551852564653286600424178746097592246778758639404203222081966425738435419428307014
else do
/* Formula */
a = 3*Sqrt(33); zz = (1+Curt(19+a)+Curt(19-a))/3
end
return zz/1
Twinprimes:
/* Twin primes constant */
procedure
/* Fast value */
zz = 0.660161815846869573927812110014555778432623360284733413319448423335405642304495277143760031413839867911779
return zz/1
Vanderpauw:
/* Van der Pauw constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 4.532360141827193809627682945716666810171861467723795584186016547940600953721305102259083879604016089653
else
/* Formula */
zz = Pi()/Ln(2)
return zz/1
Viswanath:
/* Viswanath constant */
procedure
/* Fast value */
zz = 1.1319882487943
return zz/1
Wallis:
/* Wallis constant = real root of x^3-2x-5 */
procedure
if Digits() < 101 then
/* Fast value */
zz = 2.09455148154232659148238654057930296385730610562823918030412852904531218998348366714626728177715776
else do
/* Formula */
a = Sqrt(1929); zz = Curt((45-a)/18)+Curt((45+a)/18)
end
return zz/1
Weierstrass:
/* Weierstrass constant */
procedure expose glob.
if Digits() < 101 then
/* Fast value */
zz = 0.474949379987920650332504636327982968559549373217202982283331024864557929174883860274275641250502144418903
else
/* Formula */
zz = Pow(2,1.25)*Sqrt(Pi())*Exp(Pi()*0.125)/Gamma(0.25)**2
return zz/1
Zscore:
/* Z-score 97.5 percentile constant */
procedure
/* Fast value */
zz = 1.95996398454005423552459443052055152795555007786954839847695264636163527414488266779825470949281420601799
return zz/1
Functions
/* Functions library - Build 5 Dec 2024 */
/* (C) Paul van den Eertwegh 2023-2024 */
/* Only real arguments and results supported */
Ackermann:
/* Ackermann's function */
procedure
arg xx,yy
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
if yy < 0 then say argument
/* Fast values */
if xx = 0 then
return yy+1
if xx = 1 then
return yy+2
if xx = 2 then
return yy+yy+3
if xx = 3 then
return 2**(yy+3)-3
if xx = 4 then do
if yy = 0 then
return 2**(2**2)-3
if yy = 1 then
return 2**(2**(2**2))-3
if yy = 2 then
return 2**(2**(2**(2**2)))-3
end
/* Cf definition */
if yy = 0 then
return Ackermann(xx-1,1)
else
return Ackermann(xx-1,Ackermann(xx,yy-1))
Acos:
/* Arc cosine */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if Abs(xx) > 1 then say argument
/* Formula */
return Pi()/2-Asin(xx)
Acosh:
/* Arc cosine hyperbolic */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx < 1 then say argument
/* Formula */
return Ln(xx+Sqrt(xx*xx-1))
Acot:
/* Arc cotangent */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Formula */
return Acos(xx/Sqrt(xx*xx+1))
Acoth:
/* Arc cotangent hyperbolic */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx < 1 then say argument
/* Formula */
return Ln((xx+1)/(xx-1))*0.5
Acsc:
/* Arc cosecant */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx < 1 then say argument
/* Formulas */
if xx > 0 then
return Asin(1/xx)
else
return -(Pi()+Asin(1/xx))
Acsch:
/* Arc cosecant hyperbolic */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx = 0 then say argument
/* Formula */
zz = 1/xx
return Ln(zz+Sqrt(zz*zz+1))
Agmean:
/* Arithmetic geometric mean */
procedure
arg xx,yy
if \ Number(xx) then say argument
if xx <= 0 then say argument
if \ Number(yy) then say argument
if yy < 0 then say argument
/* Fast values */
if yy = 0 then
return 0
if xx = yy then
return xx
/* Series */
numeric digits Digits()+2
vx = xx+1
do until xx = vx
numeric fuzz 0
vx = xx; vy = yy
xx = (vx+vy)*0.5; yy = Sqrt(vx*vy)
numeric fuzz 2
end
numeric fuzz 0
numeric digits Digits()-2
return xx/1
Aliquot:
/* Aliquot function = Sum of all divisors of xx including 1 */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx = 1 then
return 1
/* Euclid's method */
return Sigma(xx)-xx
Alog:
/* Antilog = 10^x */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Formula */
return Pow(10,xx)
Amean:
/* Arithmetic mean */
procedure
arg xx,yy
if \ Number(xx) then say argument
if \ Number(yy) then say argument
/* Formula */
return (xx+yy)/2
Asec:
/* Arc secant */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx < 1 then say argument
/* Formula */
return Sign(xx)*Acos(1/xx)
Asech:
/* Arc secant hyperbolic */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx <= 0 then say argument
if xx > 1 then say argument
/* Formula */
zz = 1/xx
return Ln(zz+Sqrt(zz*zz-1))
Asin:
/* Arc sine */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if Abs(xx) > 1 then say argument
/* Acos is faster for xx in [3/4,1) */
if Abs(xx) >= 0.75 then
return Sign(xx)*Acos(Sqrt(1-xx*xx))
/* Taylor series */
numeric digits Digits()+2
numeric fuzz 2
t = xx; zz = xx; xx = xx*xx
do n = 2 by 2 until zz = v
v = zz
t = t*xx*(n-1)/n; zz = zz+t/(n+1)
end
numeric digits Digits()-2
return zz/1
Asinh:
/* Arc sine hyperbolic */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Formula */
return Ln(xx+Sqrt(xx*xx+1))
Atan:
/* Arc tangent */
procedure
arg xx
if \ Number(xx) then say argument
/* Twice argument reduction */
numeric digits Digits()+2
do 2
xx = xx/(1+Sqrt(xx*xx+1))
end
/* Taylor series */
numeric fuzz 2
t = xx; zz = xx; xx = xx*xx
do n = 3 by 2 until zz = v
v = zz
t = -t*xx; zz = zz+t/n
end
zz = 4*zz
numeric digits Digits()-2
return zz/1
Atanh:
/* Arc tangent hyperbolic */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if Abs(xx) >= 1 then say argument
/* Formula */
return Ln((1+xx)/(1-xx))*0.5
Atan2:
/* Arc tangent correct quadrant */
procedure expose glob.
arg yy,xx
if \ Number(xx) then say argument
if \ Number(yy) then say argument
if xx = 0 & yy = 0 then say argument
/* Formulas */
if xx > 0 then
return Atan(yy/xx)
if xx < 0 then
if yy < 0 then
return Atan(yy/xx)-Pi()
else
return Atan(yy/xx)+Pi()
if yy < 0 then
return -Pi()*0.5
else
return Pi()*0.5
Beta:
/* Beta */
procedure expose glob.
arg xx,yy
if \ Number(xx) then say argument
if \ Number(yy) then say argument
/* Formula */
return (Gamma(xx)*Gamma(yy))/Gamma(xx+yy)
Ceil:
/* Ceiling */
procedure
arg xx
if \ Number(xx) then say argument
/* Formulas */
if Whole(xx) then
return xx
else
return Trunc(xx)+(xx>=0)
Comb:
/* Combination = binomial coefficient */
procedure
arg xx,yy
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
if yy < 0 then say argument
/* Fast values */
if yy = 0 then
return 1
if xx = yy then
return 1
if xx < yy then
return 0
numeric digits Digits()+2
/* Reduce yy */
if xx-yy < yy then
yy = xx-yy
/* Recurring loop */
zz = xx
do i = 1 to yy-1
zz = zz*(xx-i)/(i+1)
end
numeric digits Digits()-2
return zz/1
Cos:
/* Cosine */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Digits */
d1 = Digits(); d2 = Abs(Xpon(xx))+2; d3 = d1+d2
numeric digits d3
/* Reduce xx */
xx = xx//(2*Pi())
if Abs(xx) > Pi() then
xx = xx-Sign(xx)*2*Pi()
/* Taylor */
numeric fuzz d2
t = 1; zz = 1; xx = xx*xx
do n = 2 by 2 until zz = v
v = zz
t = -t*xx/(n*(n-1)); zz = zz+t
end
numeric digits d1
return zz/1
Cosh:
/* Cosine hyperbolic */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Formula */
zz = Exp(xx)
return (zz+1/zz)*0.5
Cot:
/* Cotangent */
procedure expose glob.
arg xx
zz = Sin(xx)
if zz = 0 then say argument
/* Formula */
return Cos(xx)/zz
Coth:
/* Cotangent hyperbolic */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx = 0 then say argument
/* Formula */
return 1/Tanh(xx)
Csc:
/* Cosecant */
procedure expose glob.
arg xx
zz = Sin(xx)
if zz = 0 then say argument
/* Formula */
return 1/zz
Csch:
/* Cosecant hyperbolic */
procedure expose glob.
arg xx
if xx = 0 then say argument
/* Formula */
return 1/Sinh(xx)
Curt:
/* Cubic root = x^(1/3) */
procedure
arg xx
if \ Number(xx) then say argument
/* Fast values */
if xx = 0 then
return 0
if xx = 1 then
return 1
/* Negative argument allowed */
if xx < 0 then do
s = -1; xx = Abs(xx)
end
else
s = 1
p = Digits()
numeric digits p+2
/* Argument reduction to [0...1000) */
i = Xpon(xx); i = (i-(2*(i<0)))%3; xx = xx/1000**i
/* First guess 1 decimal accurate */
t = '4.5 17.5 45.5 94.5 170.5 279.5 427.6 620.5 864.5 1000'
do zz = 1 until Word(t,zz) > xx
end
/* Dynamic precision */
d = Digits()
do n = 1 while d > 2
d.n = d; d = d%2+1
end
d.n = 2
/* Halley */
do k = n to 1 by -1
numeric digits d.k
zz = (xx+2*zz*zz*zz)/(3*zz*zz)
end
/* Inverse reduction */
zz = zz*10**i
numeric digits p
return s*zz
Deg:
/* Radians->degrees */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Formula */
return xx*180/Pi()
Dfact:
/* Double factorial = n!! */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* In memory? */
if glob.dfact.xx <> '' then
return glob.dfact.xx
/* Fast values */
if xx < 2 then
return 1
/* Loops cf definition */
if xx//2 = 1 then do
zz = 1
do n = 3 to xx by 2
zz = zz*n
end
end
else do
zz = 2
do n = 4 to xx by 2
zz = zz*n
end
end
glob.dfact.xx = zz
return zz
Digamma:
/* Digamma */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx <= 0 & Whole(xx) then say argument
/* Fast formulas */
if xx = 0.125 then
return -0.5*Pi()-4*Ln(2)-( Pi()+Ln(Sqrt(2)+1)-Ln(Sqrt(2)-1))/Sqrt(2)-Euler()
if xx = 0.25 then
return -0.5*Pi()-3*Ln(2)-Euler()
if xx = 0.5 then
return -2*Ln(2)-Euler()
if xx = 1 then
return -Euler()
if xx > 0 & xx < 500 & Whole(xx) then
return Harmonic(xx-1)-Euler()
/* Fast series */
if xx > 0 & Half(xx) then do
xx = Trunc(xx)
zz = 0
do n = 1 to xx
zz = zz+2/(2*n-1)
end
zz = zz-2*Ln(2)-Euler()
return zz
end
numeric digits Digits()+2
/* Argument reduction */
p = Digits()
a = 0
do while xx < p
a = a+1/xx; xx = xx+1
end
/* Series using Zeta function */
zz = -0.5/xx; v = 0
do n = 2 by 2 until zz = v
numeric fuzz
v = zz
zz = zz+Zeta(1-n)/(xx**n)
numeric fuzz 2
end
/* Inverse reduction */
numeric fuzz
zz = Ln(xx)+zz-a
numeric digits Digits()-2
return zz/1
Digitprod:
/* Digital product = product(digits) */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Multiply digits */
zz = 1
do n = 1 to Length(xx) while zz <> 0
zz = zz*Substr(xx,n,1)
end
return zz
Digitroot:
/* Digital root */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Formula */
return 1+(xx-1)//9
Digitsum:
/* digitsum = sum(digits) */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Sum digits */
zz = 0
do n = 1 to Length(xx)
zz = zz+Substr(xx,n,1)
end
return zz
Divisor:
/* Divisor = sum(Divisors(x)^y) */
procedure expose glob. divi.
arg xx,yy
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
if yy = '' then
yy = 1
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
/* Get divisors */
numeric digits Digits()+2
d = Divisors(xx)
/* Loop cf definition */
select
when yy = 0 then
zz = d
when yy = 1 then do
zz = 0
do n = 1 to d
zz = zz+divi.divisor.n
end
end
when Whole(yy) then do
zz = 0
do n = 1 to d
zz = zz+divi.divisor.n**yy
end
end
otherwise do
zz = 0
do n = 1 to d
zz = zz+Pow(divi.divisor.n,yy)
end
end
end
numeric digits Digits()-2
return zz/1
Dxgamma:
/* First derivative of Gamma */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx <= 0 & Whole(xx) then say argument
/* From derivative definition */
p = Digits()
numeric digits p*2+2
d = 10**(-p)
zz = (Gamma(xx+d)-Gamma(xx))/d
numeric digits p
return zz/1
Dxzeta:
/* First derivative of Zeta */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx = 1 then say argument
/* Fast values */
if xx < 0 then
if Whole(xx) then
if Even(xx) then
return (-1)**(-0.5*xx)*Fact(-xx)*Zeta(1-xx)/(2*(2*Pi())**-xx)
if xx = -2 then
return -Zeta(3)/(4*Pi()**2)
if xx = -1 then
return 1/12-Ln(Glaisher())
if xx = 0 then
return -0.5*Ln(2*Pi())
if xx = 0.5 then
return 0.25*(Pi()+2*Euler()+6*Ln(2)+2*Ln(Pi()))*Zeta(0.5)
if xx = 2 then
return Pi()*Pi()*(Euler()+Ln(2)-12*Ln(Glaisher())+Ln(Pi()))/6
if xx > 5 then do
/* Taylor series for the Zeta derivative */
numeric digits Digits()+2
zz = 0
a = Pow(2,xx); b = Ln(4); c = a-2
do n = 1 to 10000 until zz = v
numeric fuzz
v = zz
if n//2 = 0 then
t1 = 1
else
t1 = -1
zz = zz+(t1*a*Pow(n,-xx))*(b+c*Ln(n))/(c*c)
numeric fuzz 2
end
numeric fuzz
numeric digits Digits()-2
end
else do
/* From derivative definition */
p = Digits()
numeric digits p*4
d = 10**(-p+p%5); zz = (Zeta(xx+d)-Zeta(xx))/d
numeric digits p
end
return zz/1
Erf:
/* Error */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Asymptotic series */
numeric digits Digits()+2
a = (2*xx*Exp(-xx*xx))/Sqrt(Pi()); b = 2*xx*xx
numeric fuzz 2
zz = 0; f = 1; g = 1
do n = 0 until zz = v
v = zz
zz = zz+f/g
f = f*b; g = g*(2*n+3)
end
zz = a*zz
numeric digits Digits()-2
return zz/1
Erfc:
/* Error complementary */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Formula */
return 1-Erf(xx)
Even:
/* Is a number even? */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
/* Formula */
return \ Abs(xx//2)
Exp:
/* Exponential = e^xx */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Fast values */
numeric digits Digits()+2
if Whole(xx) then
return E()**xx
/* Argument reduction */
i = xx%1
if Abs(xx-i) > 0.5 then
i = i+Sign(xx)
/* Taylor series */
numeric fuzz 2
xx = xx-i; zz = 1; t = 1
do n = 1 until zz = v
v = zz
t = (t*xx)/n; zz = zz+t
end
/* Inverse reduction */
numeric fuzz
zz = zz*E()**i
numeric digits Digits()-2
return zz/1
Fact:
/* Integer factorial = n! */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Current in memory? */
if glob.fact.xx <> '' then
return glob.fact.xx
w = xx-1
/* Previous in memory? */
if glob.fact.w = '' then do
/* Loop cf definition */
zz = 1
do n = 2 to xx
zz = zz*n
end
glob.fact.xx = zz
end
else
/* Multiply */
glob.fact.xx = glob.fact.w*xx
return glob.fact.xx
Factorial:
/* Real factorial = x! */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx < 0 & Whole(xx) then say argument
/* Fast values */
if Whole(xx) then
return Fact(xx)
/* Formula */
return Gamma(xx+1)
Ffact:
/* Falling factorial */
procedure expose glob.
arg xx,yy
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
/* In memory? */
if glob.ffact.xx.yy <> '' then
return glob.ffact.xx.yy
/* Fast values */
if xx < 2 then
return 1
if yy = 0 then
return 1
/* Calculate cf definition */
zz = 1
do k = 0 to yy-1
zz = zz*(xx-k)
end
glob.ffact.xx.yy = zz
return zz
Floor:
/* Floor */
procedure
arg xx
if \ Number(xx) then say argument
/* Formula */
if Whole(xx) then
return xx
else
return Trunc(xx)-(xx<0)
Frac:
/* Fractional part */
procedure
arg xx
if \ Number(xx) then say argument
/* Formula */
return xx-xx%1
Gamma:
/* Gamma */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx < 1 & Whole(xx) then say argument
/* Fast values */
if xx < 0 then do
if Half(xx) then do
i = Abs(Floor(xx)); zz = (-1)**i*2**(2*i)*Fact(i)*Sqrt(Pi())/Fact(2*i)
return zz/1
end
end
if xx > 0 then do
if Whole(xx) then
return Fact(xx-1)
if Half(xx) then do
i = Floor(xx); zz = Fact(2*i)*Sqrt(Pi())/(2**(2*i)*Fact(i))
return zz/1
end
end
p = Digits()
if p < 61 then do
/* Lanczos with predefined coefficients */
/* Map negative xx to positive xx */
if xx < 0 then
return Pi()/(Gamma(1-xx)*Sin(Pi()*xx))
/* Argument reduction to (0.5...1.5) */
numeric digits p+2
c = Trunc(xx); xx = xx-c
if xx < 0.5 then do
xx = xx+1; c = c-1
end
/* Series coefficients 1/Gamma(xx) in 80 digits Fransen & Wrigge */
c.1 = 1.00000000000000000000000000000000000000000000000000000000000000000000000000000000
c.2 = 0.57721566490153286060651209008240243104215933593992359880576723488486772677766467
c.3 = -0.65587807152025388107701951514539048127976638047858434729236244568387083835372210
c.4 = -0.04200263503409523552900393487542981871139450040110609352206581297618009687597599
c.5 = 0.16653861138229148950170079510210523571778150224717434057046890317899386605647425
c.6 = -0.04219773455554433674820830128918739130165268418982248637691887327545901118558900
c.7 = -0.00962197152787697356211492167234819897536294225211300210513886262731167351446074
c.8 = 0.00721894324666309954239501034044657270990480088023831800109478117362259497415854
c.9 = -0.00116516759185906511211397108401838866680933379538405744340750527562002584816653
c.10 = -0.00021524167411495097281572996305364780647824192337833875035026748908563946371678
c.11 = 0.00012805028238811618615319862632816432339489209969367721490054583804120355204347
c.12 = -0.00002013485478078823865568939142102181838229483329797911526116267090822918618897
c.13 = -0.00000125049348214267065734535947383309224232265562115395981534992315749121245561
c.14 = 0.00000113302723198169588237412962033074494332400483862107565429550539546040842730
c.15 = -0.00000020563384169776071034501541300205728365125790262933794534683172533245680371
c.16 = 0.00000000611609510448141581786249868285534286727586571971232086732402927723507435
c.17 = 0.00000000500200764446922293005566504805999130304461274249448171895337887737472132
c.18 = -0.00000000118127457048702014458812656543650557773875950493258759096189263169643391
c.19 = 0.00000000010434267116911005104915403323122501914007098231258121210871073927347588
c.20 = 0.00000000000778226343990507125404993731136077722606808618139293881943550732692987
c.21 = -0.00000000000369680561864220570818781587808576623657096345136099513648454655443000
c.22 = 0.00000000000051003702874544759790154813228632318027268860697076321173501048565735
c.23 = -0.00000000000002058326053566506783222429544855237419746091080810147188058196444349
c.24 = -0.00000000000000534812253942301798237001731872793994898971547812068211168095493211
c.25 = 0.00000000000000122677862823826079015889384662242242816545575045632136601135999606
c.26 = -0.00000000000000011812593016974587695137645868422978312115572918048478798375081233
c.27 = 0.00000000000000000118669225475160033257977724292867407108849407966482711074006109
c.28 = 0.00000000000000000141238065531803178155580394756670903708635075033452562564122263
c.29 = -0.00000000000000000022987456844353702065924785806336992602845059314190367014889830
c.30 = 0.00000000000000000001714406321927337433383963370267257066812656062517433174649858
c.31 = 0.00000000000000000000013373517304936931148647813951222680228750594717618947898583
c.32 = -0.00000000000000000000020542335517666727893250253513557337960820379352387364127301
c.33 = 0.00000000000000000000002736030048607999844831509904330982014865311695836363370165
c.34 = -0.00000000000000000000000173235644591051663905742845156477979906974910879499841377
c.35 = -0.00000000000000000000000002360619024499287287343450735427531007926413552145370486
c.36 = 0.00000000000000000000000001864982941717294430718413161878666898945868429073668232
c.37 = -0.00000000000000000000000000221809562420719720439971691362686037973177950067567580
c.38 = 0.00000000000000000000000000012977819749479936688244144863305941656194998646391332
c.39 = 0.00000000000000000000000000000118069747496652840622274541550997151855968463784158
c.40 = -0.00000000000000000000000000000112458434927708809029365467426143951211941179558301
c.41 = 0.00000000000000000000000000000012770851751408662039902066777511246477487720656005
c.42 = -0.00000000000000000000000000000000739145116961514082346128933010855282371056899245
c.43 = 0.00000000000000000000000000000000001134750257554215760954165259469306393008612196
c.44 = 0.00000000000000000000000000000000004639134641058722029944804907952228463057968680
c.45 = -0.00000000000000000000000000000000000534733681843919887507741819670989332090488591
c.46 = 0.00000000000000000000000000000000000032079959236133526228612372790827943910901464
c.47 = -0.00000000000000000000000000000000000000444582973655075688210159035212464363740144
c.48 = -0.00000000000000000000000000000000000000131117451888198871290105849438992219023663
c.49 = 0.00000000000000000000000000000000000000016470333525438138868182593279063941453996
c.50 = -0.00000000000000000000000000000000000000001056233178503581218600561071538285049997
c.51 = 0.00000000000000000000000000000000000000000026784429826430494783549630718908519485
c.52 = 0.00000000000000000000000000000000000000000002424715494851782689673032938370921241
/* Series expansion */
xx = xx-1; s = 0
do k = 52 by -1 to 1
s = s*xx+c.k
end
zz = 1/s
/* Undo reduction */
if c = -1 then
zz = zz/xx
else do
do i = 1 to c
zz = (xx+i)*zz
end
end
end
else do
xx = xx-1
/* Spouge */
/* Estimate digits and iterations */
q = Floor(p*1.5); a = Floor(p*1.1)
numeric digits q
/* Series */
s = 0
do k = 1 to a-1
s = s+((-1)**(k-1)*Pow(a-k,k-0.5)*Exp(a-k))/(Fact(k-1)*(xx+k))
end
s = s+Sqrt(2*Pi()); zz = Pow(xx+a,xx+0.5)*Exp(-a-xx)*s
end
/* Normalize */
numeric digits p
return zz/1
Gcd:
/* Greatest common divisor */
procedure
arg xx,yy
if \ Number(xx) then say argument
if \ Number(yy) then say argument
/* Fast values */
xx = Abs(xx); yy = Abs(yy)
if yy = 0 then
return xx
/* Euclidian division */
do until yy = 0
parse value xx//yy yy with yy xx
end
return xx
Gmean:
/* Geometric mean */
procedure
arg xx,yy
if \ Number(xx) then say argument
if \ Number(yy) then say argument
/* Formula */
return Sqrt(xx*yy)
Half:
/* Is a number half integer? */
procedure
arg xx
if \ Number(xx) then say argument
/* Formula */
return (Frac(Abs(xx))=0.5)
Isqrt:
/* Integer square root = Floor(xx^(1/2)) */
procedure
arg xx
if \ Number(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx < 1 then
return 0
if xx < 4 then
return 1
if xx < 9 then
return 2
/* Uses only integers */
xx = xx%1; q = 1
do until q > xx
q = q*4
end
zz = 0
do while q > 1
q = q%4; t = xx-zz-q; zz = zz%2
if t >= 0 then do
xx = t; zz = zz+q
end
end
return zz
Lambda1:
/* Dirichlet lambda */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Formula */
return (1-Pow(2,-xx))*Zeta(xx)
Lambertw0:
/* Lambert W0 */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Fast values */
if xx = 0 then
return 0
numeric digits Digits()+2
/* Argument reduction */
e = E()
select
when xx > E() then do
a = Ln(xx); zz = a-Ln(a)
end
when xx > 0 then
zz = xx/E()
when xx >= -1/E() then do
a = E()*xx; b = a+1; c = Sqrt(b); zz = (a*Ln(1+c))/(b+c)
end
otherwise
say xx argument
end
/* Halley */
numeric fuzz 2
do until zz = v
v = zz
a = Exp(zz); b = a*zz; zz = zz-(b-xx)/(a+b-((zz+2)*(b-xx))/(2*zz+2))
end
numeric fuzz
numeric digits Digits()-2
return zz/1
Lambertwm1:
/* Lambert W-1 */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx < -1/E() then say argument
if xx >= 0 then say argument
/* Argument reduction */
numeric digits Digits()+2
select
when xx > -0.25 then do
a = Ln(-xx); zz = a-Ln(-a)
end
when xx > -1/E() then do
zz = -1-Sqrt(2)*Sqrt(E()*xx+1)
end
end
/* Halley */
numeric fuzz 2
do until zz = v
v = zz
a = Exp(zz); b = a*zz; zz = zz-(b-xx)/(a+b-((zz+2)*(b-xx))/(2*zz+2))
end
numeric fuzz
numeric digits Digits()-2
return zz/1
Lcm:
/* Least common multiple function */
procedure
arg xx,yy
if \ Number(xx) then say argument
if \ Number(yy) then say argument
/* Fast values */
xx = Abs(xx); yy = Abs(yy)
if yy = 0 then
return 0
/* Euclid */
a = xx*yy
do until yy = 0
parse value xx//yy yy with yy xx
end
return a%xx
Ln:
/* Natural logarithm */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx <= 0 then say argument
/* Fast values */
if xx = 1 then
return 0
p = Digits()
/* In memory? */
if glob.ln.xx.p <> '' then
return glob.ln.xx.p
/* Precalculated values */
if xx = 2 & p < 101 then do
glob.ln.xx.p = Ln2()
return glob.ln.xx.p
end
if xx = 4 & p < 101 then do
glob.ln.xx.p = Ln4()
return glob.ln.xx.p
end
if xx = 8 & p < 101 then do
glob.ln.xx.p = Ln8()
return glob.ln.xx.p
end
if xx = 10 & p < 101 then do
glob.ln.xx.p = Ln10()
return glob.ln.xx.p
end
numeric digits p+2
/* Argument reduction */
yy = xx; i = 0; e = 1/E()
if yy < 0.5 then do
zz = 1/yy
do while zz > 1.5
zz = zz*e; i = i-1
end
yy = 1/zz
end
if yy > 1.5 then do
do while yy > 1.5
yy = yy*e; i = i+1
end
end
/* Taylor series */
q = (yy-1)/(yy+1); f = q; zz = q; v = q; q = q*q
do n = 3 by 2
f = f*q; zz = zz+f/n
if zz = v then
leave
v = zz
end
numeric digits p
/* Inverse reduction */
glob.ln.xx.p = 2*zz+i
return glob.ln.xx.p
Log:
/* Briggs logarithm */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Formula */
return Ln(xx)/Ln(10)
Logxy:
/* Logarithm xx base yy */
procedure expose glob.
arg xx,yy
if \ Number(xx) then say argument
if \ Number(yy) then say argument
if yy = 1 then say argument
/* Formula */
return Ln(xx)/Ln(yy)
Mant:
/* Mantissa */
procedure
arg xx
if \ Number(xx) then say argument
/* Fast values */
if xx = 0 then
return 0
/* Formula */
zz = xx*1E+99999
return Left(zz,Pos('E',zz)-1)
Nroot:
/* Nth root = x^(1/y) */
procedure expose glob.
arg xx,yy
if \ Number(xx) then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
if yy < 1 then say argument
if xx < 0 & Even(yy) then say argument
/* Fast values */
if xx = 0 then
return 0
if xx = 1 then
return 1
/* Formulas using faster methods */
if yy = 2 then
return Sqrt(xx)
if yy = 3 then
return Curt(xx)
if yy = 4 then
return Qurt(xx)
/* Calculate */
sx = Sign(xx); xx = Abs(xx)
p1 = Digits(); p2 = p1+2
numeric digits 3
/* First guess low accuracy */
zz = 1/Exp(Ln(xx)/yy)
numeric digits p2
/* Dynamic precision */
d = p2
do k = 1 while d > 4
d.k = d; d = d%2+1
end
d.k = 4
/* Halley */
a = 1/yy; b = yy+1
do j = k to 1 by -1
numeric digits d.j
zz = zz*a*(b-xx*zz**yy)
end
zz = 1/zz
if sx < 0 then
zz = -zz
numeric digits p1
return zz/1
Number:
/* Is xx a number? */
procedure
arg xx
return Datatype(xx,'n')
Odd:
/* Is a number odd? */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
/* Formula */
return Abs(xx//2)
Perm:
/* Permutations */
procedure
arg xx,yy
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
if xx < 0 then say argument
if yy < 0 then say argument
if xx < yy then say argument
/* Cf definition */
zz = 1
do n = (xx-yy)+1 to xx
zz = zz*n
end
return zz
Pow:
/* Power = x^y */
procedure expose glob.
arg xx,yy
if \ Number(xx) then say argument
if \ Number(yy) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 0
if yy = 0 then
return 1
if Whole(yy) then
return xx**yy
/* Formulas */
if Abs(yy//1) = 0.5 then
return Sqrt(xx)**Sign(yy)*xx**(yy%1)
else
return Exp(yy*Ln(xx))
Powmod:
/* Power modulus = x^(y mod z) */
procedure
arg xx,yy,zz
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
if yy < 0 then say argument
if \ Number(zz) then say argument
if \ Whole(zz) then say argument
if zz < 1 then say argument
/* Fast values */
if zz = 1 then
return 0
/* Binary method */
numeric digits Max(Length(Format(xx,,,0)),Length(Format(yy,,,0)),2*Length(Format(zz,,,0)))
b = xx//zz; rr = 1
do while yy > 0
if yy//2 then
rr = rr*xx//zz
xx = xx*xx//zz; yy = yy%2
end
return rr
Prim:
/* Primorial = p# */
procedure expose glob. prim.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 1
/* Get primes up to the xth one */
p = Primes(Primecount(xx))
/* Calculate product */
zz = 1
numeric digits Digits()+2
do n = 1 to p
zz = zz*prim.prime.n
end
numeric digits Digits()-2
return zz/1
Primecount:
/* Prime count = Pi() function */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx = 1 then
return 0
/* Estimate number of primes up to x */
return Round(xx/(Ln(xx)-1))
Primeest:
/* Nth prime number estimate */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Estimate */
select
when xx <= 5 then do
zz = xx+xx+1
end
when xx <= 12 then do
a = Ln(xx); b = Ln(a); zz = xx*(a+b)
end
when xx <= 200 then do
a = Ln(xx); b = Ln(a); zz = xx*(a+b-1+1.8*b/a)
end
otherwise do
a = Ln(xx); b = Ln(a); zz = xx*(a+b-0.9385)+100
end
end
return Trunc(zz)
Primorial:
/* Primorial = p# */
procedure expose prim.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx < 2 then
return 1
/* Get primes up to xx */
p = Primes(xx)
/* Calculate product */
zz = 1
numeric digits Digits()+2
do n = 1 to p
zz = zz*prim.prime.n
end
numeric digits Digits()-2
return zz/1
Qurt:
/* Quartic root = x^(1/4) */
procedure
arg xx
if \ Number(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 0
if xx = 1 then
return 1
p = Digits()
numeric digits p+2
/* Argument reduction to [0...10000) */
i = Xpon(xx); i = (i+(i<0))%4-(i<0); xx = xx/10000**i
/* First guess 1 decimal accurate */
t = '8.5 48.5 168.5 440.5 960.5 1848.5 3248.5 5328.5 8280.5 10000'
do zz = 1 until Word(t,zz) > xx
end
/* Dynamic precision */
d = Digits()
do n = 1 while d > 2
d.n = d; d = Trunc(0.75*d)
end
d.n = 2
/* Halley */
f1 = 0.75; f2 = 0.25*xx
do k = n to 1 by -1
numeric digits d.k
zz = f1*zz+f2/(zz*zz*zz)
end
numeric digits p
/* Inverse reduction */
return zz*10**i
Rad:
/* Degrees->radians */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Formula */
return xx*Pi()/180
Radical:
/* Radical = product of unique prime factors */
procedure expose ufac.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Get unique factors */
n = Ufactors(xx)
/* Calculate product */
zz = 1
do i = 1 to n
zz = zz*ufac.factor.i
end
return zz
Rand:
/* Random number */
procedure expose glob.
arg xx,yy
if xx <> '' then do
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
if xx >= yy then say argument
end
/* Fixed precision */
p = Digits(); numeric digits 30
/* Get and save first seed from system Date and Time */
if glob.rand = '' then do
a = Date('s'); b = Time('l')
glob.rand = Substr(b,10,3)||Substr(b,7,2)||Substr(b,4,2)||Substr(b,1,2)||Substr(a,7,2)||Substr(a,5,2)||Substr(a,3,2)
end
/* Calculate next random number cf HP calculators */
glob.rand = Right((glob.rand*2851130928467),15)
/* Uniform deviate [0,1) */
zz = '0.'Left(glob.rand,Length(glob.rand)-3)
if xx <> '' then
zz = Floor(zz*(yy+1-xx)+xx)
numeric digits 12
return zz/1
Repunit:
/* Repeated 1's */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Formula */
return Copies('1',xx)
Rfact:
/* Rising factorial */
procedure expose glob.
arg xx,yy
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx = 0 then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
if yy < 0 then say argument
/* In memory? */
if glob.Rfact.xx.yy <> '' then
return glob.Rfact.xx.yy
/* Fast values */
if xx = 1 then
return 1
if yy = 0 then
return 1
/* Cf definition */
zz = 1
do k = 0 to yy-1
zz = zz*(xx+k)
end
glob.Rfact.xx.yy = zz
return zz
Round:
/* Round to specified decimals */
procedure
arg xx,yy
if yy = '' then
yy = Digits()
if \ Number(xx) then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
/* Format */
if yy < 0 then do
yy = Abs(yy); a = 10**yy
zz = Format(xx/a,,0,0)*a
end
else
zz = Format(xx,,yy,0)
return zz/1
Sci:
/* Convert to scientific format */
procedure
arg xx
if \ Number(xx) then say argument
/* Force format */
return Format(xx,,,,0)
Sec:
/* Secant */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
zz = Cos(xx)
if zz = 0 then say argument
/* Formula */
return 1/zz
Sech:
/* Secant hyperbolic */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Formula */
return 1/Cosh(xx)
Sigma:
/* Sigma = Sum of all divisors of x including 1 and x */
procedure expose divi.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx = 1 then do
divi.0 = 1
return 1
end
/* Euclid's method */
m = xx//2; zz = 1+xx; n = 2
do j = 2+m by 1+m while j*j < xx
if xx//j = 0 then do
zz = zz+j+xx%j; n = n+2
end
end
if j*j = xx then do
zz = zz+j; n = n+1
end
/* Store number of divisors */
divi.0 = n
/* Return sum */
return zz
Sin:
/* Sine */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Digits */
d1 = Digits(); d2 = Abs(Xpon(xx))+2; d3 = d1+d2
numeric digits d3
/* Argument reduction */
p = Pi(); xx = xx//(2*p)
if Abs(xx) > p then
xx = xx-Sign(xx)*2*p
/* Taylor series */
t = xx; zz = xx; xx = xx*xx
numeric fuzz d2
do n = 2 by 2 until zz = v
v = zz
t = -t*xx/(n*(n+1)); zz = zz+t
end
numeric digits d1
return zz/1
Sinh:
/* Sine hyperbolic */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Formula */
zz = Exp(xx)
return (zz-1/zz)*0.5
Sqrt:
/* Square root = x^(1/2) */
procedure
arg xx
if \ Number(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 0
if xx = 1 then
return 1
p = Digits()
/* Predefined values */
if xx = 2 & p < 101 then
return Sqrt2()
if xx = 3 & p < 101 then
return Sqrt3()
if xx = 5 & p < 101 then
return Sqrt5()
numeric digits p+2
/* Argument reduction to [0...100) */
i = Xpon(xx); i = (i-(i<0))%2; xx = xx/100**i
/* First guess 1 decimal accurate */
t = '2.5 6.5 12.5 20.5 30.5 42.5 56.5 72.5 90.5 100'
do zz = 1 until Word(t,zz) > xx
end
/* Dynamic precision */
d = Digits()
do n = 1 while d > 2
d.n = d; d = d%2+1
end
d.n = 2
/* Heron */
do k = n to 1 by -1
numeric digits d.k
zz = (zz+xx/zz)*0.5
end
numeric digits p
return zz*10**i
Std:
/* Convert to standard format */
procedure
arg xx
if \ Number(xx) then say argument
/* Force format */
return Format(xx,,,0)
Tan:
/* Tangent */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
zz = Cos(xx)
if zz = 0 then say argument
/* Formula */
return Sin(xx)/zz
Tanh:
/* Tangent hyperbolic */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
/* Formula */
zz = Exp(2*xx)
return (zz-1)/(zz+1)
Tau2:
/* Ramanujan Tau */
procedure expose divi.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Niebur series */
numeric digits Digits()+2
s = 0; a = 18*xx*xx
do n = 1 to xx-1
b = n*n
s = s+b*(35*b-52*n*xx+a)*Sigma(n)*Sigma(xx-n)
end
zz = xx**4*Sigma(xx)-24*s
numeric digits Digits()-2
return zz/1
Totient:
/* Euler's totient function = Phi */
procedure expose fact.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx < 3 then
return 1
if xx < 5 then
return 2
/* Multiplicative property using Factors */
f = Factors(xx)+1; fact.factor.f = 0
zz = 1; v = fact.factor.1; n = 1
do i = 2 to f
a = fact.factor.i
if a = v then
n = n+1
else do
zz = zz*v**(n-1)*(v-1)
v = a; n = 1
end
end
return zz
Trigamma:
/* Trigamma */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx <= 0 & Whole(xx) then say argument
/* Fast values */
if xx = 1 then
return Zeta(2)
numeric digits Digits()+2
p = Digits()
/* Argument reduction */
a = 0
do while xx < p
a = a+1/(xx*xx); xx = xx+1
end
/* Series using Bernoulli numbers */
zz = 0; v = 0
do n = 2 by 2
zz = zz+Bernoulli(n)/xx**(n+1)
if zz = v then
leave
v = zz
end
/* Inverse reduction and result */
zz = zz+1/xx+1/(2*xx*xx)+a
numeric digits Digits()-2
return zz/1
Whole:
/* Is a number integer? */
procedure
arg xx
/* Formula */
return Datatype(xx,'w')
Xpon:
/* Exponent */
procedure
arg xx
if \ Number(xx) then say argument
/* Formula */
numeric digits 9
if xx = 0 then
return 0
else
return Right(xx*1E+99999999,9)-99999999
Zeta:
/* Zeta */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if xx = 1 then say argument
/* Fast values */
if xx < 0 & Whole(xx) then
if Even(xx) then
return 0
if xx = 0 then
return -0.5
if xx = 3 then
return Apery()
if xx < 0 & Whole(xx) then
if Odd(xx) then
return ((-1)**-xx*Bernoulli(1-xx))/(1-xx)
if xx > 0 & Whole(xx) then
if Even(xx) then
return ((-1)**(xx/2+1)*Bernoulli(xx)*(2*Pi())**xx)/(2*Fact(xx))
if xx < 0 then
return -2*Factorial(-xx)*Sin(Pi()*-xx/2)*Zeta(1-xx)/Pow(Pi()*2,1-xx)
/* Selected odd integers fast cf Plouffe */
p = Digits()
numeric digits p+2
if xx > 2 & xx < 22 & Whole(xx) then do
if Odd(xx) then do
select
when xx = 3 then do
a = 180; b = 7; c = 360; d = 0
end
when xx = 5 then do
a = 1470; b = 5; c = 3024; d = 84
end
when xx = 7 then do
a = 56700; b = 19; c = 113400; d = 0
end
when xx = 9 then do
a = 18523890; b = 625; c = 37122624; d = 74844
end
when xx = 11 then do
a = 425675250; b = 1453; c = 851350500; d = 0
end
when xx = 13 then do
a = 257432175; b = 89; c = 514926720; d = 62370
end
when xx = 15 then do
a = 390769879500; b = 13687; c = 781539759000; d = 0
end
when xx = 17 then do
a = 1904417007743250; b = 6758333; c = 3808863131673600; d = 29116187100
end
when xx = 19 then do
a = 21438612514068750; b = 7708537; c = 42877225028137500; d = 0
end
when xx = 21 then do
a = 1881063815762259253125; b = 68529640373; c = 3762129424572110592000; d = 1793047592085750
end
end
s1 = 0; s2 = 0; v1 = 0; v2 = 0
do n = 1 to 1000
m = n**xx; e = Exp(2*Pi()*n); q = m*e
s1 = s1+1/(q-m); s2 = s2+1/(q+m)
if s1 = v1 & s2 = v2 then
leave
v1 = s1; v2 = s2
end
zz = (b*Pi()**xx-c*s1-d*s2)/a
numeric digits p
return zz/1
end
end
/* Standard for all other xx */
/* Max iterations estimate */
select
when p < 15 then
n = p*2
when p < 89 then
n = p*3
otherwise
n = p*4
end
/* Argument reduction */
a = (-1)/(2**n*(1-Pow(2,1-xx)))
/* Series */
s = 0; zz = 0
do j = 0 to 2*n-1
b = (-1)**j; c = Pow(j+1,xx)
if j < n then
s = 0
else
s = s+Comb(n,j-n)
zz = zz+(s-2**n)*b/c
end
/* Inverse reduction */
zz = a*zz
numeric digits Digits()-2
return zz/1
Numbers
/* Numbers library - Build 5 Dec 2024 */
/* (C) Paul van den Eertwegh 2023-2024 */
Abundant:
/* Is a number abundant? */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx < 101 then do
a = '12 18 20 24 30 36 40 42 48 54 56 60 66 70 72 78 80 84 88 90 96 100'
if Wordpos(xx,a) = 0 then
return 0
else
return 1
end
/* Cf definition */
if Sigma(xx) > 2*xx then
return 1
else
return 0
Alcuin:
/* Alcuin numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx < 4 then
return 0
/* Formula */
if Even(xx) then
return Round(xx*xx/48)
else
return Round((xx+3)**2/48)
Almostprime:
/* Is a number almost k-prime? */
procedure expose glob. fact.
arg xx,yy
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
if yy < 1 then say argument
/* Fast values */
if yy = 1 then
return Prime(xx)
if yy = 2 then
return Semiprime(xx)
/* Cf definition */
if Factors(xx) = yy then
return 1
else
return 0
Arithmetic:
/* Is a number arithmetic? */
procedure expose divi.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx < 101 then do
a = '1 3 5 6 7 11 13 14 15 17 19 20 21 22 23 27 29 30 31 33 ',
|| '35 37 38 39 41 42 43 44 45 46 47 49 51 53 54 55 56 57 59 60 61 62 65 66 ',
|| '67 68 69 70 71 73 77 78 79 83 85 86 87 89 91 92 93 94 95 96 97 99 '
if Wordpos(xx,a) = 0 then
return 0
else
return 1
end
/* Cf definition */
s = Sigma(xx)
if Whole(s/divi.0) then
return 1
else
return 0
Bell:
/* Bell numbers */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 1
if xx = 1 then
return 1
/* Recurring */
numeric digits Digits()+2
if xx < 36 then do
zz = 0
do k = 0 to xx
zz = zz+Stirling2(xx,k)
end
end
else do
zz. = 0; zz.0 = 1; zz.1 = 1
do n = 2 to xx
s = 0
do k = 0 to n-1
s = s+Comb(n-1,k)*zz.k
end
zz.n = s
end
zz = zz.xx
end
numeric digits Digits()-2
return zz/1
Beraha:
/* Beraha numbers */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 1 then
return 4
if xx = 2 then
return 0
if xx = 3 then
return 1
if xx = 4 then
return 2
if xx = 6 then
return 3
if xx = 8 then
return 2+Sqrt(2)
if xx = 10 then
return 0.5*(5+Sqrt(5))
/* Formula */
return 2+2*Cos(2*Pi()/xx)
Bernoulli:
/* Bernoulli numbers */
procedure expose glob. work.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 1
if xx = 1 then
return 0.5
if xx//2 = 1 then
return 0
p = Digits()
/* In memory? */
if glob.bernoulli.xx.p <> '' then
return glob.bernoulli.xx.p
/* Take extra digits */
numeric digits p+xx
/* Recurring method Akiyama-Tanigawa */
do m = 0 by 1 to xx
work.m = 1/(m+1)
do j = m by -1 to 1
k = j-1; work.k = j*(work.k-work.j)
end
end
numeric digits p
/* Result */
zz = work.0+0
glob.bernoulli.xx.p = zz
return zz
Cake:
/* Cake numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Formula */
return (xx*xx*xx+5*xx+6)/6
Catalan2:
/* Catalan numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Recurring */
numeric digits Digits()+2
zz = 1
do n = 1 to xx
zz = zz*(4*n-2)/(n+1)
end
numeric digits Digits()-2
return zz/1
Caterer:
/* Lazy caterer's numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Formula */
return (xx*xx+xx+2)/2
Central:
/* Central binomial coefficient numbers */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Formula */
return Comb(2*xx,xx)
Chowla:
/* Chowla numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Formula */
return Aliquot(xx)-1
Composite:
/* Is a number composite? */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 2 then say argument
/* Fast values */
if xx < 101 then do
c = '4 6 8 9 10 12 14 15 16 18 20 21 22 24 25 26 27 28 30 32 33 34 35 36 38 39 ',
|| '40 42 44 45 46 48 49 50 51 52 54 55 56 57 58 60 62 63 64 65 66 68 69 70 72 ',
|| '74 75 76 77 78 80 81 82 84 85 86 87 88 90 91 92 93 94 95 96 98 99 100 '
if Wordpos(xx,c) = 0 then
return 0
else
return 1
end
if xx//2 = 0 then
return 1
if xx//3 = 0 then
return 1
if Right(xx,1) = 5 then
return 1
/* Method trial division */
do n = 5 by 6 while n*n <= xx
if xx//n = 0 then
return 1
if xx//(n+2) = 0 then
return 1
end
return 0
Conway1:
/* Conway look-and-say numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Series cf definition */
zz = '1'
do n = 1 to xx
ns = ''; c = 1; m = Length(zz)
do j = 1 to m
if j = m | Substr(zz,j,1) <> Substr(zz,j+1,1) then do
ns = ns||c||Substr(zz,j,1); c = 1
end
else
c = c+1
end
zz = ns
end
return zz
Coprime:
/* Are 2 numbers coprime? */
procedure
arg xx,yy
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
/* Formula */
return (Gcd(xx,yy) = 1)
Cullen:
/* Cullen numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Formula */
return xx*2**xx+1
Deficient:
/* Is a number deficient? */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx < 101 then do
d = '1 2 3 4 5 7 8 9 10 11 13 14 15 16 17 19 21 22 23 25 26 27 29 31 32 33 34 35 ',
|| '37 38 39 41 43 44 45 46 47 49 50 51 52 53 55 57 58 59 61 62 63 64 65 67 68 ',
|| '69 71 73 74 75 76 77 79 81 82 83 85 86 87 89 91 92 93 94 95 97 98 99 '
if Wordpos(xx,d) = 0 then
return 0
else
return 1
end
/* Cf definition */
if Sigma(xx) < 2*xx then
return 1
else
return 0
Derangement:
/* Derangement numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Recurring cf definition */
numeric digits Digits()+2
a = 1; b = 0; zz = 0
do n = 2 to xx
zz = (a+b)*(n-1)
a = b; b = zz
end
numeric digits Digits()-2
return zz/1
Favard:
/* Favard numbers */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 1
if xx = 1 then
return Pi()*0.5
if xx = 2 then
return Pi()**2*0.125
if xx = 3 then
return Pi()**3/24
if xx = 4 then
return 5*Pi()**4/384
if xx = 5 then
return Pi()**5/240
if xx = 6 then
return 61*Pi()**6/46080
if xx = 7 then
return 17*Pi()**7/40320
if xx = 8 then
return 277*Pi()**8/2064384
if xx = 9 then
return 31*Pi()**9/725760
if xx = 10 then
return 50521*Pi()**10/3715891200
if xx = 11 then
return 691*Pi()**11/159667200
if xx = 12 then
return 540553*Pi()**12/392398110720
numeric digits Digits()+2
/* Recurring */
zz.0 = 1; zz.1 = Pi()*0.5
do j = 2 to xx
s = 0
do k = 1 to Floor(j*0.5)
a = 2*k; b = a-1; c = j-a
s = s+zz.b*zz.c
end
zz.j = s*Pi()/(2*j)
end
numeric digits Digits()-2
return zz.xx/1
Fermat:
/* Fermat numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
numeric digits Digits()+2
/* Formula */
zz = 2**(2**xx)
numeric digits Digits()-2
return zz/1
Ffactor:
/* First prime factor */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 2 then say argument
/* Fast values */
if xx < 4 then
return xx
/* Check low factors */
n = 0
pr = '2 3 5 7 11 13 17 19 23'
do i = 1 to Words(pr)
p = Word(pr,i)
if xx//p = 0 then
return p
end
/* Check higher factors */
do j = 29 by 6 while j*j <= xx
p = Right(j,1)
if p <> 5 then
if xx//j = 0 then
return j
if p = 3 then
iterate
k = j+2
if xx//k = 0 then
return k
end
/* Last factor */
if xx > 1 then
return xx
return 0
Fibonacci:
/* Fibonacci numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx < 2 then
return xx
/* Recurring */
numeric digits Digits()+2
a = 0; b = 1
do n = 2 to xx
zz = a+b; a = b; b = zz
end
numeric digits Digits()-2
return zz/1
Goldbach:
/* Goldbach numbers */
procedure expose prim.
arg xx
if \ Number(xx) then say argument
if \ Even(xx) then say argument
if xx < 4 then say argument
/* Scan primes */
p = Primes(xx); zz = 0
do i = 2 to xx%2
if prim.flag.i then do
j = xx-i
if prim.flag.j then do
zz = zz+1
end
end
end
return zz/1
Golomb2:
/* Golomb-Silverman numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx < 1 then
return 1
/* Recurring */
numeric digits Digits()+2
zz. = 0; zz.1 = 1
do n = 2 to xx
a = n-1; b = zz.a; c = zz.b; d = n-c
zz.n = 1+zz.d
end
numeric digits Digits()-2
return zz.xx/1
Gould:
/* Gould numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 1
/* Recurring */
numeric digits Digits()+2
zz. = 0; zz.0 = 1
do n = 1 to xx
if Even(n) then do
a = n%2; zz = zz.a
end
else do
a = n%2; zz = 2*zz.a
end
zz.n = zz
end
numeric digits Digits()-2
return zz.xx/1
Gregory1:
/* Gregory numbers 1 */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx = 1 then
return 0.5
/* Recurring */
numeric digits Digits()+2
zz.1 = 0.5
if xx = 1 then
return zz.1
do n = 2 to xx
s = 0
do k = 1 to n-1
s = s+zz.k/(n+1-k)
end
zz.n = -s+1/(n+1)
end
numeric digits Digits()-2
return (-1)**(xx-1)*zz.xx
Gregory2:
/* Gregory numbers 2 */
procedure
arg xx
if \ Number(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx = 1 then
return 0.25*Pi()
/* Formula */
return Atan(1/xx)
Harmonic:
/* Harmonic numbers */
procedure
arg xx,yy
if yy = '' then
yy = 1
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
if yy < 0 then say argument
/* Fast values */
if xx = 0 then
return 0
if xx < 2 then
return 1
numeric digits Digits()+2
/* From definition */
zz = 0
if yy = 1 then do
do n = 1 to xx
zz = zz+1/n
end
end
else do
do n = 1 to xx
zz = zz+1/n**yy
end
end
numeric digits Digits()-2
return zz/1
Highcomposite:
/* Is a number highly composite? */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* ... to do */
return 0
Home:
/* Home prime numbers */
procedure expose fact. glob. work.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Run thru chain */
numeric digits 25
do while Factors(xx) > 1
xx = ''
do i = 1 to fact.0
xx = xx||fact.factor.i
end
end
return xx
Jacobsthal:
/* Jacobsthal numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx < 3 then
return 1
numeric digits Digits()+2
/* Formula */
zz = (2**xx-(-1)**xx)/3
numeric digits Digits()-2
return zz/1
Kaprekar:
/* Is a number Kaprekar? */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx < 101 then do
k = '1 9 45 55 99'
if Wordpos(xx,k) = 0 then
return 0
else
return 1
end
/* Method casting out nines */
p = Max(Digits(),2*Length(xx))
numeric digits p
a = xx//9
if a > 2 then
return 0
s = xx*xx
if a = s//9 then do
do i = 1 to Length(s)%2
parse var s l +(i) r
if xx = l+r then
return 1
end
end
return 0
Lah:
/* Lah numbers */
procedure expose glob.
arg xx,yy
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
if yy < 1 then say argument
if xx < yy then say argument
/* Fast values */
if xx = yy then
return 1
/* Formulas */
s = (-1)**xx
if yy = 1 then
return s*Fact(xx)
else
return s*Comb(xx-1,yy-1)*Fact(xx)/Fact(yy)
Lambda2:
/* Lambda numbers */
procedure expose efac.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx < 3 then
return 1
if xx < 5 then
return 2
/* Using Efactors and Lcm */
f = Efactors(xx)
zz = 1
do i = 1 to f
p = efac.factor.i
e = efac.exponent.i
if p = 2 & e > 2 then
zz = Lcm(zz,2**(e-2))
else
zz = Lcm(zz,(p-1)*p**(e-1))
end
return zz
Lebesgue1:
/* Lebesgue numbers */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 1
if xx = 1 then
return 1/3+2*Sqrt(3)/Pi()
if xx = 2 then
return 0.2+Sqrt(25-2*Sqrt(5))/Pi()
if xx = 3 then
return 1/7+(22*Sin(Pi()/7)-2*Cos(Pi()/14)+10*Cos(3*Pi()/14))/(3*Pi())
if xx = 4 then
return 13/(2*Sqrt(3)*Pi())+1/9+(7*Sin(2*Pi()/9)-5*Sin(Pi()/9)-Cos(Pi()/18))/Pi()
numeric digits Digits()+2
/* Series expansion */
zz = 0
do n = 1 to xx
zz = zz+Tan(n*Pi()/(2*xx+1))/n
end
zz = 1/(2*xx+1)+2*zz/Pi()
numeric digits Digits()-2
return zz/1
Leonardo:
/* Leonardo numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx < 3 then
return 1
/* From definition */
a = 1; b = 1
do n = 3 to xx
zz = a+b+1
a = b; b = zz
end
return zz/1
Lucas:
/* Lucas numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 1 then
return 2
if xx = 2 then
return 1
/* Recurring */
numeric digits Digits()+2
a = 2; b = 1; zz = 0
do n = 2 to xx
zz = a+b
a = b; b = zz
end
numeric digits Digits()-2
return zz/1
Magic:
/* Magic numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Formula */
return (xx*xx*xx+xx)/2
Metallic:
/* Metallic ratio numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 1
if xx = 1 then
return Golden()
if xx = 2 then
return Silver()
if xx = 3 then
return Bronze()
/* Formula */
return 0.5*(xx+Sqrt(xx*xx+4))
Moebius:
/* Moebius numbers */
procedure expose glob. fact. ufac.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Using number of (unique) prime factors */
call Factors(xx)
call Ufactors(xx)
if fact.0 = ufac.0 then
if Even(fact.0) then
return 1
else
return -1
else
return 0
Motzkin:
/* Motzkin numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx < 3 then
return 1
numeric digits Digits()+2
/* Recurring */
a = 1; b = 1; zz = 0
do n = 2 to xx
zz = ((3*n-3)*a+(2*n+1)*b)/(n+2)
a = b; b = zz
end
numeric digits Digits()-2
return zz/1
Narayana:
/* Narayana cows numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx < 3 then
return 1
/* Recurring */
numeric digits Digits()+2
a = 1; b = 1; c = 1; zz = 0
do n = 3 to xx
zz = a+c
a = b; b = c; c = zz
end
numeric digits Digits()-2
return zz/1
Padovan:
/* Padovan numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx < 3 then
return 1
numeric digits Digits()+2
/* Recurring */
a = 1; b = 1; c = 1; zz = 0
do n = 3 to xx
zz = a+b
a = b; b = c; c = zz
end
numeric digits Digits()-2
return zz/1
Partition:
/* Partition numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 1
numeric digits Digits()+2
/* Recurring */
yy. = 0; yy.0 = 1
do n = 1 to xx
s = 0
do k = 1 to n
a = n-k*(3*k-1)/2; b = n-k*(3*k+1)/2
s = s+(-1)**(k+1)*(yy.a+yy.b)
end
yy.n = s
end
numeric digits Digits()-2
return yy.xx/1
Pell1:
/* Pell numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx < 2 then
return xx
numeric digits Digits()+2
/* Recurring */
a = 0; b = 1; zz = 0
do n = 2 to xx
zz = a+2*b
a = b; b = zz
end
numeric digits Digits()-2
return zz/1
Pell2:
/* Pell-Lucas companion numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx < 2 then
return 2
/* Recurring */
numeric digits Digits()+2
a = 2; b = 2; zz = 0
do n = 2 to xx
zz = a+2*b
a = b; b = zz
end
numeric digits Digits()-2
return zz/1
Perfect:
/* Is a number perfect? */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
p = '6 28 496 8128 33550336 8589869056 137438691328 2305843008139952128 ',
|| '2658455991569831744654692615953842176 ',
|| '191561942608236107294793378084303638130997321548169216 ',
|| '13164036458569648337239753460458722910223472318386943117783728128 ',
|| '14474011154664524427946373126085988481573677491474835889066354349131199152128 '
if Wordpos(xx,p) = 0 then
return 0
else
return 1
Perrin:
/* Perrin numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 3
if xx = 1 then
return 0
if xx = 2 then
return 2
numeric digits Digits()+2
/* Recurring */
a = 3; b = 0; c = 2; zz = 0
do n = 3 to xx
zz = a+b
a = b; b = c; c = zz
end
numeric digits Digits()-2
return zz/1
Persistence:
/* Additive persistence */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast value */
if xx = 0 then
return 0
/* Cf definition */
do zz = 1 until xx < 10
xx = Digitsum(xx)
end
return zz
Pollardrho:
/* Find one prime factor */
procedure
arg xx
/* Init */
numeric digits Length(xx)+2
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 2 then say argument
/* Method Pollard Rho */
a = 2; b = 2; yy = 1
do while yy = 1
a = (a*a+1)//xx; b = (b*b+1)//xx; b = (b*b+1)//xx
yy = Gcd(Abs(a-b),xx)
end
if xx = yy then
return yy
else
return Min(yy,Trunc(xx/yy))
Practical:
/* Is a number practical? */
procedure expose fact.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx < 101 then do
p = '1 2 4 6 8 12 16 18 20 24 28 30 32 36 40 42 ',
|| '48 54 56 60 64 66 72 78 80 84 88 90 96 100 '
if Wordpos(xx,p) = 0 then
return 0
else
return 1
end
if Odd(xx) then
return 0
/* Method Srinivasan-Stewart-Sierpinski */
n = Factors(xx)
f = 2; s = 2
do i = 2 to n
if fact.factor.i > s+1
then return 0
f = f*fact.factor.i; s = Sigma(f)
end
return 1
Prime:
/* Is a number prime? */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Low primes also used as deterministic witnesses */
lp = '2 3 5 7 11 13 17 19 23 29 31 37 41'
/* Fast values */
if xx < 2 then
return 0
if xx < 42 then do
if Wordpos(xx,lp) = 0 then
return 0
else
return 1
end
if xx//2 = 0 then
return 0
if xx//3 = 0 then
return 0
if Right(xx,1) = 5 then
return 0
/* Miller-Rabin primality test */
numeric digits 2*Length(xx)
d = xx-1; e = d
/* Reduce xx-1 by factors of 2 */
do s = -1 while d//2 = 0
d = d%2
end
/* Thresholds deterministic witnesses */
th = '2047 1373653 25326001 3215031751 2152302898747 3474749660383 341550071728321 0 ',
|| '3825123056546413051 0 0 318665857834031151167461 3317044064679887385961981 '
w = Words(th)
/* Up to 13 deterministic trials */
if xx < Word(th,w) then do
do k = 1 to w
if xx < Word(th,k) then
leave
end
end
/* or 3 probabilistic trials */
else do
lp = ''
do k = 1 to 3
r = Rand(2,e)/1; lp = lp||r||' '
end
k = k-1
end
/* Algorithm using generated witnesses */
do i = 1 to k
a = Word(lp,i); zz = Powmod(a,d,xx)
if zz = 1 then
iterate
if zz = e then
iterate
do s
zz = (zz*zz)//xx
if zz = 1 then
return 0
if zz = e then
leave
end
if zz <> e then
return 0
end
return 1
Pronic:
/* Pronic numbers */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Formula */
numeric digits Digits()+2
zz = xx*xx+xx
numeric digits Digits()-2
return zz/1
Recaman:
/* Recaman numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 0
/* Recurring cf definition */
zz. = 0; zz.0 = 0; s. = 0; s.0 = 1
do n = 1 to xx
m = n-1; a = zz.m-n
if a > 0 & s.a = 0 then do
zz.n = a; s.a = 1
end
else do
b = zz.m+n
zz.n = b; s.b = 1
end
end
return zz.xx
Semiprime:
/* Is a number semi prime? */
procedure expose prim.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Low semiprimes */
s = '4 6 9 10 14 15 21 22 25 26 33 34 35 38 39 46 49 ',
|| '51 55 57 58 62 65 69 74 77 82 85 86 87 91 93 94 95 '
/* Fast values */
if xx < 4 then
return 0
if xx < 101 then do
if Wordpos(xx,s) = 0 then
return 0
else
return 1
end
/* Wheeled scan */
do i = 2 for 2
if xx//i = 0 then
if Prime(xx%i) then
return 1
else
return 0
end
do i = 5 by 6 until i*i > xx
do j = i by 2 for 2
if xx//j = 0 then
if Prime(xx%j) then
return 1
else
return 0
end
end
return 0
Sorting:
/* Sorting numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 3
if xx = 1 then
return 0
if xx = 2 then
return 2
/* Recurring */
zz = 0; i = xx-1; z = 1
do while i >= 0
zz = zz+i; i = i-z; z = z+z
end
return zz/1
Stirling1:
/* Stirling numbers 1 */
procedure expose glob.
arg xx,yy
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
if yy < 0 then say argument
/* Fast values */
if yy = xx then
return 1
if yy > xx then
return 0
if yy = 0 then
return 0
/* Formulas */
s = (-1)**(xx-yy)
if yy = 1 then
return s*Fact(xx-1)
if yy = 2 then
return s*Round(Fact(xx-1)*Harmonic(xx-1))
if yy = 3 then
return s*Round(Fact(xx-1)*(Harmonic(xx-1)**2-Harmonic(xx-1,2))/2)
if yy = xx-3 then
return s*Comb(xx,2)*Comb(xx,4)
if yy = xx-2 then
return s*Round((3*xx-1)*Comb(xx,3)/4)
if yy = xx-1 then
return s*Comb(xx,2)
numeric digits Digits()+2
/* Definition */
zz. = 0; zz.1 = 1
do i = 1 to xx-1
a = i
do j = i+1 to 1 by -1
b = j-1; zz.j = zz.b+a*zz.j
end
end
numeric digits Digits()-2
return s*zz.yy
Stirling2:
/* Stirling numbers 2 */
procedure expose glob.
arg xx,yy
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
if \ Number(yy) then say argument
if \ Whole(yy) then say argument
if yy < 0 then say argument
if xx < yy then say argument
/* Fast values */
if xx = 0 then
return 0
if yy = 0 then
return 0
if xx = yy then
return 1
if yy = 1 then
return 1
if yy = 2 then
return 2**(xx-1)-1
if yy = 3 then
return (3**xx-3*2**xx+3)/6
if yy = xx-1 then
return Comb(xx,2)
numeric digits Digits()+2
/* Definition */
zz. = 1; zz = xx-yy
do i = 2 to yy
do j = 1 to zz
a = j-1; zz.j = zz.j+i*zz.a
end
end
numeric digits Digits()-2
return zz.zz/1
Sylvester:
/* Sylvester numbers */
procedure
arg xx
if \ Whole(xx) then say argument
if \ Number(xx) then say argument
if xx < 1 then say argument
if xx > 33 then say argument
numeric digits Digits()+2
/* Definition */
zz = 2
do n = 2 to xx
zz = zz*zz-zz+1
end
numeric digits Digits()-2
return zz/1
Tetranacci1:
/* Tetranacci numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx < 4 then
return 0
/* Recurring */
a = 0; b = 0; c = 0; d = 1
do n = 3 to xx
zz = a+b+c; a = b; b = c; c = d; d = zz
end
return zz/1
Thue:
/* Thue-Morse numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Concatenate 2s complements */
zz = 0
do i = 1 to xx
zz = zz||Translate(zz,10,01)
end
return zz
Tribonacci1:
/* Tribonacci numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx < 3 then
return 0
/* Recurring */
a = 0; b = 0; c = 1
do n = 3 to xx
zz = a+b+c; a = b; b = c; c = zz
end
return zz/1
Ulam:
/* Ulam numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx < 3 then
return xx
/* Series */
numeric digits Digits()+2
zz.1 = 1; zz.2 = 2; d = 2; e.= 0; e.1 = 1; e.2 = 1; z = 3
do until d = xx
n = 0
do j = 1 to d
b = z-zz.j
if e.b then do
if zz.j <> b then do
n = n+1
if n > 2 then
leave j
end
end
end
if n = 2 then do
d = d+1; zz.d = z; e.z = 1
end
z = z+1
end
zz = zz.d
numeric digits Digits()-2
return zz/1
Wedderburn:
/* Wedderburn numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx < 2 then
return xx
/* Recurring */
numeric digits Digits()+2
zz. = 0; zz.1 = 1
do n = 2 to xx
if Even(n) then do
a = n%2; s = zz.a*(zz.a+1)/2
end
else do
a = n%2+1; s = 0
end
do i = 1 to a-1
j = n-i; s = s+zz.i*zz.j
end
zz.n = s
end
numeric digits Digits()-2
return zz.xx/1
Woodall:
/* Woodall numbers */
procedure
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Formula */
numeric digits Digits()+2
zz = xx*2**xx-1
numeric digits Digits()-2
return zz/1
ZigZag:
/* Zigzag alternating permutations numbers */
procedure expose glob.
arg xx
if \ Number(xx) then say argument
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Fast values */
if xx = 0 then
return 1
if xx = 1 then
return 1
/* Recurring */
numeric digits Digits()+2
zz. = 0; zz.0 = 1; zz.1 = 1
do n = 2 to xx
s = 0
do k = 0 to n-1
a = Comb(n-1,k); b = n-k-1
s = s+a*zz.k*zz.b
end
zz.n = s/2
end
zz = zz.xx
numeric digits Digits()-2
return zz/1
Polynomial
/* Polynomial library - Build 5 Dec 2024 */
/* (C) Paul van den Eertwegh 2024 */
/* Coefficients are coded as string, highest first */
/* Example ax^3+cx = 'a 0 c 0' */
Padd:
/* Addition */
procedure expose poly.
arg xx,yy
if xx = '' then say argument
if yy = '' then say argument
/* Add */
wx = Words(xx); wy = Words(yy); zz = Max(wx,wy)
poly. = 0; poly.0 = zz
a = zz-wx; b = zz-wy
do i = 1 to wx
j = a+i; poly.coef.j = Word(xx,i)
end
do i = 1 to wy
j = b+i; poly.coef.j = poly.coef.j+Word(yy,i)
end
return zz
Parr2form:
/* Array -> Formula */
procedure expose poly.
/* Generate formula */
zz = ''; wm = poly.0
do i = 1 to wm
a = poly.coef.i
if a <> 0 then do
select
when a < 0 then
s = '-'
when i > 1 then
s = '+'
otherwise
s = ''
end
a = Abs(a); e = wm-i
if a = 1 & e > 0 then
a = ''
select
when e > 1 then
b = 'x^'e
when e = 1 then
b = 'x'
otherwise
b = ''
end
zz = zz||s||a||b
end
end
if zz = '' then
zz = 0
return Strip(zz)
Parr2lst:
/* Array -> List */
procedure expose poly.
zz = ''
do i = 1 to poly.0
zz = zz poly.coef.i
end
return Strip(zz)
Pdif:
/* Differentiation */
procedure expose poly.
arg xx
if xx = '' then say argument
/* dif */
wx = Words(xx); zz = wx-1
poly. = 0; poly.0 = zz
do i = 1 to zz
poly.coef.i = (zz-i+1)*Word(xx,i)
end
return zz
Pdiv:
/* Long division (in progress) */
procedure
arg xx,yy
if xx = '' then say argument
if yy = '' then say argument
/* Divide... to do */
return 0
Peval:
/* Evaluation */
procedure
arg xx,yy
if xx = '' then say argument
if yy = '' then say argument
if \ Number(yy) then say argument
/* Evaluate */
zz = 0
numeric digits Digits()+2
do n = 1 to Words(xx)
zz = zz*yy+Word(xx,n)
end
numeric digits Digits()-2
/* Normalize */
return zz/1
Plst2arr:
/* List -> Array */
procedure
arg xx
if xx = '' then say argument
/* Generate array */
zz = Words(xx)
poly. = 0; poly.0 = zz
do i = 1 to zz
poly.coef.i = Word(xx,i)
end
return zz
Plst2form:
/* List -> Formula */
procedure
arg xx
if xx = '' then say argument
/* Generate formula */
zz = ''; wm = Words(xx)
do i = 1 to wm
a = Word(xx,i)
if a <> 0 then do
select
when a < 0 then
s = '-'
when i > 1 then
s = '+'
otherwise
s = ''
end
a = Abs(a); e = wm-i
if a = 1 & e > 0 then
a = ''
select
when e > 1 then
b = 'x^'e
when e = 1 then
b = 'x'
otherwise
b = ''
end
zz = zz||s||a||b
end
end
if zz = '' then
zz = 0
return zz
Pmul:
/* Multiplication */
procedure expose poly. work.
arg xx,yy
if xx = '' then say argument
if yy = '' then say argument
/* Multiply */
wx = Words(xx); wy = Words(yy)
do i = 1 to wx
work.coef.1.i = Word(xx,i)
end
do i = 1 to wy
work.coef.2.i = Word(yy,i)
end
numeric digits Digits()+2
zz = wx+wy-1
poly. = 0; poly.0 = zz
do i = 1 to wx
do j = 1 to wy
k = i+j-1; poly.coef.k = poly.coef.k+work.coef.1.i*work.coef.2.j
end
end
numeric digits Digits()-2
/* Normalize coefs */
call Pnorm
/* Convert to list */
return zz
Pnorm:
/* Normalize coefs */
procedure expose poly.
do i = 1 to poly.0
poly.coef.i = poly.coef.i/1
end
return poly.0
Ppow:
/* Exponentiation */
procedure expose poly. comb. work.
arg xx,yy
if xx = '' then say argument
if \ Whole(yy) then say argument
if yy < 0 then say argument
/* Exponentiate */
numeric digits Digits()+2
wx = Words(xx); zz = wx*yy-yy+1
poly. = 0; poly.0 = zz
select
when wx = 1 then
/* Power of a number */
poly.coef.1 = xx**yy
when wx = 2 then do
/* Newton's binomial */
call Combinations -yy
a = Word(xx,1); b = Word(xx,2)
do i = 1 to zz
j = yy-i+1; k = i-1
poly.coef.i = comb.yy.k*a**j*b**k
end
end
otherwise do
/* Repeated multiplication */
do i = 1 to wx
poly.coef.1.i = Word(xx,i)
poly.coef.2.i = poly.coef.1.i
end
wy = wx
do i = 2 to yy
work. = 0
do j = 1 to wx
do k = 1 to wy
l = j+k-1; work.coef.l = work.coef.l+poly.coef.1.j*poly.coef.2.k
end
end
if i = yy then
leave i
wx = wx+wy-1
do j = 1 to wx
poly.coef.1.j = work.coef.j
end
end
do i = 1 to zz
poly.coef.i = work.coef.i
end
end
end
numeric digits Digits()-2
/* Normalize coefs */
call Pnorm
return zz
Psub:
/* Polynomial subtraction */
procedure expose poly.
arg xx,yy
if xx = '' then say argument
if yy = '' then say argument
/* Subtract */
wx = Words(xx); wy = Words(yy); zz = Max(wx,wy)
poly. = 0; poly.0 = zz
a = zz-wx; b = zz-wy
do i = 1 to wx
j = a+i; poly.coef.j = Word(xx,i)
end
do i = 1 to wy
j = b+i; poly.coef.j = poly.coef.j-Word(yy,i)
end
return zz
Rational
/* Rational library - Build 5 Dec 2024 */
/* (C) Paul van den Eertwegh 2024 */
/* Rationals are coded as string 'num den' */
/* Example 123/456 = '123 456' */
Rabs:
/* Absolute value */
procedure
arg xx
parse var xx nx dx
if dx = '' then
dx = 1
nx = Abs(nx); dx = Abs(dx)
return nx dx
Radd:
/* Add */
procedure
arg xx,yy
parse var xx nx dx
if dx = '' then
dx = 1
parse var yy ny dy
if dy = '' then
dy = 1
return nx*dy+ny*dx dx*dy
Rdiv:
/* Divide */
procedure
arg xx,yy
parse var xx nx dx
if dx = '' then
dx = 1
parse var yy ny dy
if dy = '' then
dy = 1
return nx*dy dx*ny
Rinv:
/* Invert */
procedure
arg xx
parse var xx nx dx
if dx = '' then
dx = 1
return dx nx
Rmul:
/* Multiply */
procedure
arg xx,yy
parse var xx nx dx
if dx = '' then
dx = 1
parse var yy ny dy
if dy = '' then
dy = 1
return nx*ny dx*dy
Rneg:
/* Negate */
procedure
arg xx
parse var xx nx dx
if dx = '' then
dx = 1
return -nx dx
Rpow:
/* Power */
procedure
arg xx,yy
parse var xx nx dx
if dx = '' then
dx = 1
return nx**yy dx**yy
Rrat:
/* Float -> Rational */
procedure
arg xx
in = xx; h = 10**(Digits()-1)
/* Starting values */
num = 0; den = 1; tnum = 1; tden = 0
/* Limit precision */
do while tnum <= h & tden <= h
/* Integer part */
n = Trunc(xx)
/* Calculate numerator and denominator */
z = tnum; tnum = n*tnum+num; num = z
z = tden; tden = n*tden+den; den = z
/* Check precision */
if n = xx | tnum/tden = in then do
if tnum > h | tden > h then
leave
/* Possible final values */
num = tnum; den = tden
leave
end
/* Next round */
xx = 1/(xx-n)
end
return num den
Rsimp:
/* Simplify */
procedure
arg xx
parse var xx nx dx
if dx = '' then
dx = 1
g = Gcd(nx,dx)
return nx/g dx/g
Rsub:
/* Subtract */
procedure
arg xx,yy
parse var xx nx dx
if dx = '' then
dx = 1
parse var yy ny dy
if dy = '' then
dy = 1
return nx*dy-ny*dx dx*dy
Roots
/* Roots library - Build 5 Dec 2024 */
/* (C) Paul van den Eertwegh 2024 */
/* Real coefficients and real roots */
/* Coefficients are coded as string, highest first */
/* Example ax^3+cx = 'a 0 c' */
Cueq:
/* Roots of cubic ax^3+bx^2+cx+d = 0 */
procedure expose cueq. glob.
arg xx; xx = xx 0 0 0 0
parse var xx a b c d .
if \ Number(a) then say argument
if \ Number(b) then say argument
if \ Number(c) then say argument
if \ Number(d) then say argument
if a = 0 then say argument
/* Method Cardano et al */
numeric digits Digits()*2+2
/* Reduce to x^3+ax^2+bx+c */
parse value b/a c/a d/a with a1 b1 c1
/* Reduce to x^3+ax+b */
h1 = a1*a1; h2 = h1*a1
a2 = b1-h1/3; b2 = -h2/27+h2/9-a1*b1/3+c1
/* Discriminant */
s = Round(b2*b2/4+a2*a2*a2/27,digits()-2)
/* Roots */
cueq. = 0
select
when s < 0 then do
h1 = Abs(a2)/3
f = Acos(-b2/(2*Sqrt(h1*h1*h1)))
h1 = 2*Sqrt(h1); h2 = f/3; h3 = Pi()/3; h4 = a1/3
x1 = h1*Cos(h2)-h4; x2 = -h1*Cos(h2-h3)-h4; x3 = -h1*Cos(h2+h3)-h4
zz = 1; cueq.root.zz = x1
if x2 <> x1 then do
zz = zz+1; cueq.root.zz = x2
end
if x3 <> x1 & x3 <> x2 then do
zz = zz+1; cueq.root.zz = x3
end
end
when s = 0 then do
h1 = Curt(-0.5*b2); h2 = a1/3
x1 = 2*h1-h2; x2 = -h1-h2
zz = 1; cueq.root.zz = 2*h1-h2
if x2 <> x1 then do
zz = zz+1; cueq.root.zz = -h1-h2
end
end
when s > 0 then do
h1 = 0.5*b2
f = Sqrt((h1)**2+(a2*a2*a2/27)); g = Curt(-h1+f); h = Curt(-h1-f)
h1 = g+h; h3 = a1/3
zz = 1; cueq.root.zz = h1-h3
end
end
/* Normalize */
numeric digits Digits()/2
do i = 1 to zz
cueq.root.i = Round(cueq.root.i,digits()-2)
end
/* Number of roots */
cueq.0 = zz
return zz
Lieq:
/* Roots of linear ax+b = 0 */
procedure expose glob.
arg xx; xx = xx 0 0
/* Coefficients */
parse var xx a b .
if \ Number(a) then say argument
if \ Number(b) then say argument
if a = 0 then say argument
/* Solution */
numeric digits Digits()*2
glob.Lieq.1 = -b/a; glob.lieq.0 = 1
numeric digits Digits()/2
/* Normalize */
glob.Lieq.1 = glob.lieq.1+0
/* Return number of roots */
return 1
Queq:
/* Roots of quartic ax^4+bx^3+cx^2+dx+e = 0 */
procedure expose glob.
arg xx; xx = xx 0 0 0 0 0
/* Coefficients */
parse var xx a b c d e .
if \ Number(a) then say argument
if \ Number(b) then say argument
if \ Number(c) then say argument
if \ Number(d) then say argument
if \ Number(e) then say argument
if a = 0 then say argument
/* Under construction */
numeric digits Digits()+2
zz = 0
/* ... */
glob.queq.0 = zz
numeric digits Digits()-2
/* Normalize */
do i = 1 to zz
glob.queq.i = glob.queq.i/1
end
/* Number of roots */
return zz
Sqeq:
/* Roots of square ax^2+bx+c = 0 */
procedure expose glob.
arg xx; xx = xx 0 0 0
parse var xx a b c .
if \ Number(a) then say argument
if \ Number(b) then say argument
if \ Number(c) then say argument
if a = 0 then say argument
/* Discriminant */
numeric digits Digits()+2
d = trunc(b*b-4*a*c,digits())
/* Abc formula */
h1 = -0.5/a
select
when d < 0 then do
zz = 0
end
when d = 0 then do
zz = 1
glob.sqeq.1 = h1*b
end
when d > 0 then do
zz = 2; h2 = Sqrt(d)
glob.sqeq.1 = h1*(b+h2)
glob.sqeq.2 = h1*(b-h2)
end
end
glob.sqeq.0 = zz
numeric digits Digits()-2
/* Normalize */
do i = 1 to zz
glob.sqeq.i = trunc(glob.sqeq.i,digits())/1
end
/* Number of roots */
return zz
Sequences
/* Sequences library - Build 5 Dec 2024 */
/* (C) Paul van den Eertwegh 2023-2024 */
Abundants:
/* Abundant number sequence */
procedure expose abun.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
abun. = 0
/* Fast values */
if xx < 101 then do
a = '12 18 20 24 30 36 40 42 48 54 56 60 66 70 72 78 80 84 88 90 96 100 999'
do zz = 1 to Words(a)
w = Word(a,zz)
if w > xx then
leave
abun.abundant.zz = w
end
zz = zz-1; abun.0 = zz
return zz
end
/* Check if sum(divisors) > 2*number */
zz = 0
do i = 1 to xx
s = Sigma(i)
if s > 2*i then do
zz = zz+1; abun.abundant.zz = i
end
end
abun.0 = zz
return zz
Additives:
/* Additive prime sequence */
procedure expose addi. prim.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
addi. = 0
/* Fast values */
if xx < 2 then
return 0
if xx < 101 then do
a = '2 3 5 7 11 23 29 41 43 47 61 67 83 89 999'
do zz = 1 to Words(a)
w = Word(a,zz)
if w > xx then
leave
addi.prime.zz = w
end
zz = zz-1; addi.0 = zz
return zz
end
/* Get primes */
p = Primes(xx)
/* Collect additive primes */
zz = 0
do i = 1 to p
q = prim.prime.i; s = 0
do j = 1 to Length(q)
s = s+Substr(q,j,1)
end
if Prime(s) then do
zz = zz+1; addi.prime.zz = q
end
end
/* Return number of additive primes */
return zz
Amicables:
/* Amicable number sequence */
procedure expose glob. amic.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
amic. = 0
/* Scan for amicable pairs */
zz = 0
do i = 1 to xx
s = Sigma(i)-i; glob.Sigma.i = s
if i = glob.Sigma.s then do
if s = i then
iterate
zz = zz+1
amic.amicable.1.zz = s; amic.amicable.2.zz = i
end
end
amic.0 = zz
return zz
Arithmetics:
/* Arithmetic number sequence */
procedure expose arit. divi.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
arit. = 0
/* Fast values */
if xx < 101 then do
a = '1 3 5 6 7 11 13 14 15 17 19 20 21 22 23 27 29 30 31 33 ',
|| '35 37 38 39 41 42 43 44 45 46 47 49 51 53 54 55 56 57 59 60 61 62 65 66 ',
|| '67 68 69 70 71 73 77 78 79 83 85 86 87 89 91 92 93 94 95 96 97 99 999 '
do zz = 1 to Words(a)
w = Word(a,zz)
if w > xx then
leave
arit.arithmetic.zz = w
end
zz = zz-1; arit.0 = zz
return zz
end
/* Check if number is Arithmetic */
zz = 0
do i = 1 to xx
if Arithmetic(i) then do
zz = zz+1; arit.arithmetic.zz = i
end
end
arit.0 = zz
return zz
Carmichaels:
/* Carmichael 3 strong prime sequence */
procedure expose carm.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
carm. = 0
/* Method Janeson */
zz = 0
do p1 = 3 by 2 to xx
if \ Prime(p1) then
iterate p1
pm = p1-1; ps = -p1*p1
do h3 = 1 to pm
t1 = (h3+p1) * pm; t2 = ps//h3
if t2 < 0 then
t2 = t2+h3
do d = 1 to h3+pm
if t1//d <> 0 then
iterate d
if t2 <> d//h3 then
iterate d
p2 = 1+t1%d
if \ Prime(p2) then
iterate d
p3 = 1+(p1*p2%h3)
if \ Prime(p3) then
iterate d
if (p2*p3)//pm <> 1 then
iterate d
zz = zz+1
carm.prime1.zz = p1; carm.prime2.zz = p2; carm.prime3.zz = p3
end d
end h3
end
carm.0 = zz
/* Return count */
return zz
Chowlas:
/* Chowla number sequence */
procedure expose chow.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
chow. = 0
/* Call aliquot */
do i = 1 to xx
chow.chowla.i = Aliquot(i)-1
end
chow.0 = xx
/* Return count */
return xx
Combinations:
/* Combination sequence */
procedure expose comb.
arg xx
if \ Whole(xx) then say argument
/* Recurring definition */
comb. = 1
if xx < 0 then do
xx = -xx; m = xx%2; a = 1
do i = 1 to m
a = a*(xx-i+1)/i; comb.xx.i = a
end
do i = m+1 to xx-1
j = xx-i; comb.xx.i = comb.xx.j
end
zz = xx+1
end
else do
do i = 1 to xx
i1 = i-1
do j = 1 to i1
j1 = j-1; comb.i.j = comb.i1.j1+comb.i1.j
end
end
zz = (xx*xx+3*xx+2)/2
end
comb.0 = zz
return zz
Composites:
/* Composite number sequence = not prime */
procedure expose comp.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
comp. = 0
/* Fast values */
if xx < 101 then do
c = '4 6 8 9 10 12 14 15 16 18 20 21 22 24 25 26 27 28 30 32 33 34 35 36 38 39 ',
|| '40 42 44 45 46 48 49 50 51 52 54 55 56 57 58 60 62 63 64 65 66 68 69 70 72 ',
|| '74 75 76 77 78 80 81 82 84 85 86 87 88 90 91 92 93 94 95 96 98 99 100 999 '
do zz = 1 to Words(c)
w = Word(c,zz)
if w > xx then
leave
comp.composite.zz = w
end
zz = zz-1; comp.0 = zz
return zz
end
/* Sieve of Eratosthenes */
zz. = 0
do i = 2 to xx while i*i <= xx
do j = i+i by i to xx
zz.j = 1
end
end
zz = 0
do i = 4 to xx
if zz.i = 1 then do
zz = zz+1
comp.composite.zz = i
end
end
comp.0 = zz
return zz
Cubans:
/* Cuban prime sequence */
procedure expose cuba.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
cuba. = 0; zz = 0
/* Generate */
a = 1; b = 8; c = 2
do forever
v = b-a
if v > xx then
leave
if Prime(v) then do
zz = zz+1; cuba.prime.zz = v
end
a = b; c = c+1; b = c*c*c
end
cuba.0 = zz
return zz
Cubics:
/* Cubic prime sequence */
procedure expose cubi. prim.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Get primes */
call Primes(xx)
/* Init */
cubi. = 0; cubi.prime.1 = 2; zz = 1
/* Generate */
a = 2; b = 3; k = 1
do while b <= xx
b = a + k*k*k
if prim.flag.b = 1 then do
zz = zz+1; cubi.prime.zz = b
a = b; k = 1
end
k = k+1
end
cubi.0 = zz
return zz
Cyclops:
/* Cyclop number sequence */
procedure expose cycl.
arg xx
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Init */
cycl. = 0; m = 0; zz = 1
/* Generate */
do f = 1
h = m+1; m = zz
do i = 1 to 9
do j = h to m
a = cycl.cyclop.j
do k = 1 to 9
b = i||a||k
if b > xx then
leave f
zz = zz+1; cycl.cyclop.zz = b
end
end
end
end
cycl.0 = zz
return zz
Deficients:
/* Deficient number sequence */
procedure expose defi.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
defi. = 0
/* Fast values */
if xx < 101 then do
a = '1 2 3 4 5 7 8 9 10 11 13 14 15 16 17 19 21 22 23 25 26 27 29 31 32 33 34 35 ',
|| '37 38 39 41 43 44 45 46 47 49 50 51 52 53 55 57 58 59 61 62 63 64 65 67 68 ',
|| '69 71 73 74 75 76 77 79 81 82 83 85 86 87 89 91 92 93 94 95 97 98 99 999'
do zz = 1 to Words(a)
w = Word(a,zz)
if w > xx then
leave
defi.deficient.zz = w
end
zz = zz-1; defi.0 = zz
return zz
end
/* Check if sum(divisors) < 2*number */
zz = 0
do i = 1 to xx
s = Sigma(i)
if s < 2*i then do
zz = zz+1
defi.deficient.zz = i
end
end
defi.0 = zz
return zz
Divisors:
/* Divisors of an integer */
procedure expose divi.
arg xx
if \ Whole(xx) then say argument
if xx < 0 then say argument
/* Init */
divi. = 0
/* Fast values */
if xx = 1 then do
divi.divisor.1 = 1; divi.0 = 1
return 1
end
/* Euclid's method */
a = 1; divi.Left.1 = 1; b = 1; divi.Right.1 = xx
m = xx//2
do j = 2+m by 1+m while j*j < xx
if xx//j = 0 then do
a = a+1; divi.Left.a = j; b = b+1; divi.Right.b = xx%j
end
end
if j*j = xx then do
a = a+1; divi.Left.a = j
end
/* Save in table */
zz = 0
do i = 1 to a
zz = zz+1; divi.divisor.zz = divi.Left.i
end
do i = b by -1 to 1
zz = zz+1; divi.divisor.zz = divi.Right.i
end
divi.0 = zz
/* Return number of divisors */
return zz
Efactors:
/* Prime factors with exponent */
procedure expose efac.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Fast values */
if xx = 1 then do
efac.0 = 0
return 0
end
if xx < 4 then do
efac.factor.1 = xx; efac.exponent.1 = 1; efac.0 = 1
return 1
end
if Prime(xx) then do
efac.factor.1 = xx; efac.exponent.1 = 1; efac.0 = 1
return 1
end
/* Check low factors */
zz = 0
pr = '2 3 5 7 11 13 17 19 23'
do i = 1 to Words(pr)
p = Word(pr,i); e = 0
do while xx//p = 0
e = e+1; xx = xx%p
end
if e > 0 then do
zz = zz+1; efac.factor.zz = p; efac.exponent.zz = e
end
end
/* Check higher factors */
do j = 29 by 6 while j*j <= xx
p = Right(j,1)
if p <> 5 then do
e = 0
do while xx//j = 0
e = e+1; xx = xx%j
end
end
if e > 0 then do
zz = zz+1; efac.factor.zz = j; efac.exponent.zz = e
end
if p = 3 then
iterate
yy = j+2; e = 0
do while xx//yy = 0
e = e+1; xx = xx%yy
end
if e > 0 then do
zz = zz+1; efac.factor.zz = yy; efac.exponent.zz = e
end
end
if xx > 1 then do
if e = 0 then do
zz = zz+1; efac.factor.zz = xx; efac.exponent.zz = 1
end
end
efac.0 = zz
/* Return number of factor pairs */
return zz
Emirps:
/* Reversed primes sequence */
procedure expose emir. prim.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Get primes */
call Primes(xx)
/* Init */
emir. = 0; zz = 0
/* Generate */
do i = 13 by 2 to xx
a = Reverse(i)
if a = i then
iterate i
if \ prim.flag.i then
iterate i
if \ prim.flag.a then
iterate i
zz = zz+1; emir.prime.zz = i
end
emir.0 = zz
return zz
Erdoss:
/* Erdos prime sequence */
procedure expose erdo. prim. glob.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Get primes */
call Primes(xx)
/* Init */
erdo. = 0; zz = 0
/* Generate */
do i = 1 to prim.0
a = prim.prime.i
do j = 1
k = Fact(j)
if k >= a then
leave j
p = a-k
if prim.flag.p then
iterate i
end
zz = zz+1; erdo.prime.zz = a
end
erdo.0 = zz
return zz
Euclids:
/* Euclid-Mullin number sequence */
procedure expose eucl.
arg xx
/* Init */
numeric digits 100
if \ Whole(xx) then say argument
if xx < 1 then say argument
if xx > 16 then say argument
/* Init */
eucl. = 0; eucl.euclid.1 = 2; eucl.0 = 1
/* Using Ffactor = first prime factor */
p = 2
do i = 2 to xx
z = p+1; t = Ffactor(z); eucl.euclid.i = t; p = p*t
end
/* Save and return number */
eucl.0 = xx
return xx
Extras:
/* Extra prime sequence */
procedure expose extr.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
extr. = 0; extr.prime.1 = 2; zz = 1
/* Generate */
do i = 3 by 2 to xx
do j = 1 to Length(i)
if Pos(Substr(i,j,1),'014689') > 0 then
iterate i
end
if \ Prime(Digitsum(i)) then
iterate i
if \ Prime(i) then
iterate i
zz = zz+1; extr.prime.zz = i
end
extr.0 = zz
return zz
Factors:
/* Prime factors */
procedure expose fact. glob.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
fact. = 0
/* Fast values */
if xx = 1 then
return 0
if Prime(xx) then do
fact.factor.1 = xx; fact.0 = 1
return 1
end
/* Check low factors */
zz = 0
pr = '2 3 5 7 11 13 17 19 23'
do i = 1 to Words(pr)
p = Word(pr,i)
do while xx//p = 0
zz = zz+1; fact.factor.zz = p
xx = xx%p
end
end
/* Check higher factors */
do j = 29 by 6 while j*j <= xx
p = Right(j,1)
if p <> 5 then do
do while xx//j = 0
zz = zz+1; fact.factor.zz = j
xx = xx%j
end
end
if p = 3 then
iterate
k = j+2
do while xx//k = 0
zz = zz+1; fact.factor.zz = k
xx = xx%k
end
end
/* Last factor */
if xx > 1 then do
zz = zz+1; fact.factor.zz = xx
end
fact.0 = zz
/* Return number of factors */
return zz
Fareys:
/* Farey fraction sequence */
procedure expose fare.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
fare. = 0
/* Recurring */
fare.farey.1 = '0/1'
zz = 1
parse value 0 1 1 xx with aa bb cc dd
do while cc <= xx
k = Trunc((xx+bb)/dd)
parse value cc dd k*cc-aa k*dd-bb with aa bb cc dd
zz = zz+1
fare.farey.yy = aa'/'bb
end
fare.0 = zz
/* Number of entries */
return zz
Frobeniuss:
/* Frobenius prime sequence */
procedure expose frob. prim.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Get primes */
p = Primes(xx%10)
/* Init */
frob. = 0; zz = 0
/* Generate */
do i = 1 to p-1
j = i+1; f = prim.prime.i * prim.prime.j - prim.prime.i - prim.prime.j
if f > xx then
leave
zz = zz+1; frob.prime.zz = f
end
frob.0 = zz
return zz
Giugas:
/* Giuga number sequence */
procedure expose giug.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
giug. = 0
/* Fast values */
if xx < 30 then
return 0
g = '30 858 1722 66198 2214408306 24423128562 432749205173838 14737133470010574 ',
|| '550843391309130318 244197000982499715087866346 554079914617070801288578559178 ',
|| '1910667181420507984555759916338506 999999999999999999999999999999999 '
do zz = 1 to Words(g)
w = Word(g,zz)
if w > xx then do
zz = zz-1
leave
end
giug.giuga.zz = w
end
giug.0 = zz
return zz
Hammings:
/* Hamming number sequence */
procedure expose hamm.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Ensure enough digits */
numeric digits 2**(Length(xx)+1)
/* Dijkstra */
hamm. = 1
x2 = 2; x3 = 3; x5 = 5
i2 = 1; i3 = 1; i5 = 1
do zz = 2
h = x2
if x3 < h then
h = x3
if x5 < h then
h = x5
hamm.hamming.zz = h
if zz = xx then
leave
if x2 = h then do
i2 = i2+1; x2 = hamm.hamming.i2+hamm.hamming.i2
end
if x3 = h then do
i3 = i3+1; x3 = hamm.hamming.i3+hamm.hamming.i3+hamm.hamming.i3
end
if x5 = h then do
i5 = i5+1; x5 = hamm.hamming.i5*5
end
end
hamm.0 = zz
return zz
Highcomposites:
/* Highly composite number sequence */
procedure expose high.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
high. = 0
/* Thresholds and increments */
a = '1 2 6 60 840 55440 720720 61261200 2327925600 321253732800 9999999999999'
b = '1 2 6 60 420 27720 360360 12252240 232792560 80313433200 9999999999999'
c = Words(a)-1; m = 0; zz = 0
/* Colllect cf definition */
do i = 1 to c
do j = Word(a,i) by Word(b,i) to Min(xx,Word(a,i+1)-1)
d = Divisors(j)
if d > m then do
zz = zz+1; high.highcomposite.zz = j
m = d
end
end
end
high.0 = zz
/* Return count */
return zz
Humbles:
/* Humble number sequence */
procedure expose humb.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Ensure enough digits */
numeric digits 2**(Length(xx)+1)
/* Dijkstra */
humb. = 1
x2 = 2; x3 = 3; x5 = 5; x7 = 7
i2 = 1; i3 = 1; i5 = 1; i7 = 1
do zz = 2
h = x2
if x3 < h then
h = x3
if x5 < h then
h = x5
if x7 < h then
h = x7
humb.humble.zz = h
if zz = xx then
leave
if x2 = h then do
i2 = i2+1; x2 = humb.humble.i2+humb.humble.i2
end
if x3 = h then do
i3 = i3+1; x3 = humb.humble.i3+humb.humble.i3+humb.humble.i3
end
if x5 = h then do
i5 = i5+1; x5 = humb.humble.i5*5
end
if x7 = h then do
i7 = i7+1; x7 = humb.humble.i7*7
end
end
humb.0 = zz
return zz
Kaprekars:
/* Kaprekar number sequence */
procedure expose kapr.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
kapr. = 0
/* Fast values */
if xx < 101 then do
k = '1 9 45 55'
do zz = 1 to Words(k)
w = Word(k,zz)
if w > xx then
leave
kapr.kaprekar.zz = w
end
zz = zz-1; kapr.0 = zz
return zz
end
xx = xx+1
/* Ensure enough digits */
p = Max(Digits(),2*Length(xx))
numeric digits p
zz = 1; kape.kaprekar.1 = 1
/* Method casting out nines */
do i = 9 for xx-9
a = i//9
if a > 2 then
iterate i
s = i*i
if a = s//9 then do
do j = 1 to Length(s)%2
parse var s l +(j) r
if i <> l+r then
iterate j
zz = zz+1; kapr.kaprekar.zz = i
leave
end
end
end
kapr.0 = zz
return zz
Perfects:
/* Perfect number sequence */
procedure expose perf.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
perf. = 0
/* Fast values */
if xx < 6 then
return 0
p = '6 28 496 8128 33550336 8589869056 137438691328 2305843008139952128 ',
|| '2658455991569831744654692615953842176 ',
|| '191561942608236107294793378084303638130997321548169216 ',
|| '13164036458569648337239753460458722910223472318386943117783728128 ',
|| '14474011154664524427946373126085988481573677491474835889066354349131199152128 ',
|| '99999999999999999999999999999999999999999999999999999999999999999999999999999'
do zz = 1 to Words(p)
w = Word(p,zz)
if w > xx then
leave
perf.perfect.zz = w
end
zz = zz-1; perf.0 = zz
return zz
Practicals:
/* Practical number sequence */
procedure expose prac. fact.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
prac. = 0
/* Fast values */
if xx < 101 then do
p = '1 2 4 6 8 12 16 18 20 24 28 30 32 36 40 42 ',
|| '48 54 56 60 64 66 72 78 80 84 88 90 96 100 999 '
do zz = 1 to Words(p)
w = Word(p,zz)
if w > xx then
leave
prac.practical.zz = w
end
zz = zz-1; prac.0 = zz
return zz
end
/* Using function practical() */
zz = 1; prac.practical.1 = 1
do i = 2 by 2 to xx
if Practical(i) then do
zz = zz+1; prac.practical.zz = i
end
end
prac.0 = zz
return zz
Primes:
/* Prime sequence */
procedure expose prim. work. glob.
arg xx
numeric digits Max(Digits(),Xpon(xx)+1)
xx = Format(xx)
if \ Whole(xx) then say argument
if xx = 0 then say argument
/* Init */
prim. = 0
/* Fast values */
if xx = 1 then
return 0
/* Nth prime or threshold? */
s = (xx<0)
if s then do
xx = Abs(xx); zz = xx; xx = Primeest(xx)
end
/* Sieve of Eratosthenes */
work. = 1
do i = 3 by 2 to xx while i*i <= xx
if work.i then do
do j = i*i by i+i to xx
work.j = 0
end
end
end
/* Save results */
zz = 1; prim.prime.1 = 2; prim.flag.2 = 1
do i = 3 by 2 to xx
if work.i then do
zz = zz+1; prim.prime.zz = i; prim.flag.i = 1
end
end
if s then
zz = zz
prim.0 = zz
return zz
Primorials:
/* Primorial sequence */
procedure expose prim. prmo. work. glob.
arg xx
numeric digits Max(Digits(),Xpon(xx)+1)
xx = Format(xx)
if \ Whole(xx) then say argument
if xx = 0 then say argument
if xx < -50000 then say argument
if xx > 1e250000 then say argument
/* Init */
prmo. = 0
/* Fast values */
if Abs(xx) = 1 then
return 0
/* Xth primorial or xx threshold? */
yy = (xx<0)
if yy then do
a = Primes(xx); xx = Abs(xx)
end
else
a = Primes(600000)
/* Multiply primes */
p = prim.prime.1; zz = 1
do i = 2 to a
numeric digits Length(p)+6
p = p*prim.prime.i
if \ yy then
if p > xx then
leave
zz = zz+1
prmo.primorial.zz = p
end
prmo.0 = zz
return zz
Quadratics:
/* Quadratic prime sequence */
procedure expose quad. prim.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Get primes */
call Primes(xx)
/* Init */
quad. = 0; quad.prime.1 = 2; zz = 1
/* Generate */
a = 2; b = 3; k = 1
do while b <= xx
b = a + k*k
if prim.flag.b = 1 then do
zz = zz+1; quad.prime.zz = b
a = b; k = 1
end
k = k+1
end
quad.0 = zz
return zz
Reversables:
/* Reversable prime sequence */
procedure expose reve. prim.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Get primes */
p = Primes(10**(Xpon(xx)+1))
/* Init */
reve. = 0; zz = 0
/* Generate */
do i = 1 to p
a = prim.prime.i
if a > xx then
leave i
b = Reverse(a)
if \ prim.flag.b then
iterate i
zz = zz+1; reve.prime.zz = a
end
reve.0 = zz
return zz
Totients:
/* Euler's totient number sequence */
procedure expose toti.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
toti. = 0
/* Recurring sequence */
do i = 1 to xx
toti.totient.i = i
end
do i = 2 to xx
if toti.totient.i < i then
iterate i
do j = i by i to xx
toti.totient.j = toti.totient.j-toti.totient.j/i
end
end
toti.0 = xx
return xx
Ufactors:
/* Unique prime factors */
procedure expose ufac.
arg xx
if \ Whole(xx) then say argument
if xx < 1 then say argument
/* Init */
ufac. = 0
/* Fast values */
if xx = 1 then
return 0
if xx < 4 then do
ufac.factor.1 = xx; ufac.0 = 1
return 1
end
if Prime(xx) then do
ufac.factor.1 = xx; ufac.0 = 1
return 1
end
/* Check low factors */
zz = 0
pr = '2 3 5 7 11 13 17 19 23'
do i = 1 to Words(pr)
p = Word(pr,i); v = xx
do while xx//p = 0
xx = xx%p
end
if xx <> v then do
zz = zz+1; ufac.factor.zz = p
end
end
/* Check higher factors */
do j = 29 by 6 while j*j <= xx
p = Right(j,1)
if p <> 5 then do
v = xx
do while xx//j = 0
xx = xx%j
end
if xx <> v then do
zz = zz+1; ufac.factor.zz = j
end
end
if p = 3 then
iterate
yy = j+2; v = xx
do while xx//yy = 0
xx = xx%yy
end
if xx <> v then do
zz = zz+1; ufac.factor.zz = yy
end
end
/* Last factor */
if xx > 1 then do
zz = zz+1; ufac.factor.zz = xx
end
ufac.0 = zz
/* Return number of factors */
return zz
Generic Quicksort
default [label]=Quicksort [lt]=< [eq]== [gt]=>
/* Sorting procedure - Build 7 Sep 2024 */
/* (C) Paul van den Eertwegh 2024 */
[label]:
/* Sort a stem on 1 or more key columns, syncing 0 or more data columns */
procedure expose (table)
arg table,keys,data
/* Collect keys */
kn = words(keys)
do x = 1 to kn
key.x = word(keys,x)
end
/* Collect data */
dn = words(data)
do x = 1 to dn
data.x = word(data,x)
end
/* Sort */
n = value(table||0); s = 1; sl.1 = 1; sr.1 = n
do until s = 0
l = sl.s; r = sr.s; s = s-1
do until l >= r
/* Up to 19 rows insertion sort is faster */
if