Mathematics.rex
Appearance
Introduction
In 2024 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 modules, stand-alone files and documentation. All files are contained in below self-extractor. Follow the instructions as given in the code and obtain the full rexx math package.
After running the self-extractor, you'll find some useful text files (among others):
Modules.txt lists all modules.
Labels.txt lists all procedures per module.
See documentation for help and tips.
Self-extractor
-- Math.rex - Mathemetics toolbox self-extractor
-- REXX Modules, snippets, programs and documentation
-- Copy and save this self-extractor in any folder. Name it as
-- you like. Run it with Regina or ooRexx. Except for the
-- version info, it will run silently unless you specify
-- parameter V (= verbose). It will create bunch of programs
-- and includes. Existing ones will be overwritten without
-- warning. Run.rex is the preprocessor and Math.inc contains
-- all math modules.
-- Modules.txt (module list)
-- Labels.txt (procedure and routine list)
-- Comment.txt (extract of all program comments)
-- Stems.txt (global stem list)
-- Crossref.txt (cross reference global stems and procedures)
-- [regina|rexx] run demo1: shows include only required modules
-- [regina|rexx] run demo2: shows include all modules in 1 file
-- Model1.rex: may be used for your own playground (recommended)
Main:
-- Main program flow
say 'MATH SELF-EXTRACTOR - 11 Apr 2025'; say
call Time('r')
parse upper arg v
verbose = (v = 'V')
call Extract
call Documentation
call Stems
call Crossreference
if verbose then
say Time('e')/1 'seconds'
exit
Extract:
-- Source generator
if verbose then
say 'Generate source code...'
parse source . . program
call Stream program,'c','open read'
math = 'Math.inc'
call Stream math,'c','open write replace'
tot = 0; module = ''
do while Lines(program) > 0
prog = Linein(program)
if Left(prog,10) = '-- Module ' then do
if module <> '' then
call Stream module,'c','close'
parse var prog . . module .
if verbose then
say Substr(prog,4,length(prog)-3)
call Stream module,'c','open write replace'
end
if module <> '' then do
if Pos('.inc',module) > 0 then
call Lineout math,prog
call Lineout module,prog
tot = tot+1
end
end
call Stream module,'c','close'
call Stream math,'c','close'
call Stream program,'c','close'
if verbose then do
say tot 'lines'
say 'Done'
say
end
return
Documentation:
-- Documentation generator
if verbose then
say 'Generate source documentation...'
modules = 'Modules.txt'
call Stream modules,'c','open write replace'
labels = 'Labels.txt'
call Stream labels,'c','open write replace'
comment = 'Comment.txt'
call Stream comment,'c','open write replace'
tot = 0
call lineout modules,'LIST OF MODULES'
call lineout modules,''
call lineout labels,'LIST OF PROCEDURES PER MODULE'
call lineout labels,''
call lineout comment,'LIST OF COMMENTS PER PROCEDURE'
call lineout comment,''
tot = tot+6
call Stream program,'c','open read'
do while Lines(program) > 0
prog = Linein(program)
select
when left(prog,10) = '-- Module ' then do
s = substr(prog,4)
parse var s . module .
prog = Linein(program)
s = substr(prog,4)
module = left('Module' module,22) s
call lineout modules,module
call lineout labels,''
call lineout labels,module
call lineout comment,''
call lineout comment,''
call lineout comment,module
tot = tot+6
end
when left(prog,2) = '--' then do
s = substr(prog,4)
call lineout comment,s
tot = tot+1
end
when right(prog,1) = ':' then do
label1 = left(prog,length(prog)-1)
prog = Linein(program)
s = substr(prog,4)
label2 = left('Label' label1,22) s
call lineout labels,label2
call lineout comment,''
call lineout comment,label2
tot = tot+3
end
otherwise
nop
end
end
call Stream program,'c','close'
call Stream modules,'c','close'
call Stream labels,'c','close'
call Stream comment,'c','close'
if verbose then do
say tot 'lines'
say 'Done'
say
end
return
Stems:
-- Global stems list
if verbose then
say 'Generate global stem list...'
stems = 'Stems.txt'
call Stream stems,'c','open write replace'
tot = 0
call lineout stems,'LIST OF GLOBAL STEMS'
call lineout stems,''
call lineout stems,'abun. Abundant numbers'
call lineout stems,'addi. Additive primes'
call lineout stems,'amic. Amicable numbers'
call lineout stems,'arit. Arithmetic numbers'
call lineout stems,'bern. Bernoulli numbers'
call lineout stems,'carm. Carmichael strong 3 primes'
call lineout stems,'cata. Catalan numbers'
call lineout stems,'cbrt. Cubic roots'
call lineout stems,'chow. Chowla numbers'
call lineout stems,'comb. Combinations'
call lineout stems,'comp. Composite numbers'
call lineout stems,'cuba. Cuban primes'
call lineout stems,'cubi. Cubic primes'
call lineout stems,'cycl. Cyclop numbers'
call lineout stems,'defi. Deficient numbers'
call lineout stems,'divi. Divisors'
call lineout stems,'efac. Exponent factors'
call lineout stems,'emir. Emirp primes'
call lineout stems,'erdo. Erdos numbers'
call lineout stems,'eucl. Euclid numbers'
call lineout stems,'extr. Extra primes'
call lineout stems,'fact. Factors'
call lineout stems,'fibo. Fibonacci numbers'
call lineout stems,'flag. Flags'
call lineout stems,'frob. Frobenius primes'
call lineout stems,'giug. Giuga numbers'
call lineout stems,'glob. Global variables'
call lineout stems,'hamm. Hamming numbers'
call lineout stems,'humb. Humble numbers'
call lineout stems,'high. High composite numbers'
call lineout stems,'kapr. Kaprekar numbers'
call lineout stems,'labl. Labels'
call lineout stems,'lirt. Linear root'
call lineout stems,'ludi. Ludic numbers'
call lineout stems,'magi. Magic numbers'
call lineout stems,'magn. Magmanimous numbers'
call lineout stems,'motz. Motzkin numbers'
call lineout stems,'perf. Perfect numbers'
call lineout stems,'poly. Polynomial coefficients'
call lineout stems,'prac. Practical numbers'
call lineout stems,'prim. Prime numbers'
call lineout stems,'prmo. Primorial numbers'
call lineout stems,'qtrt. Quartic roots'
call lineout stems,'quad. Quadratic primes'
call lineout stems,'reve. Reversable primes'
call lineout stems,'smoo. Smooth numbers'
call lineout stems,'sqrt. Square roots'
call lineout stems,'squa. Square free numbers'
call lineout stems,'toti. Totient numbers'
call lineout stems,'ufac. Unique factors'
tot = tot+43
call Stream stems,'c','close'
if verbose then do
say tot 'lines'
say 'Done'
say
end
return
Crossreference:
-- Stem cross reference lists
if verbose then
say 'Generate stem cross references...'
call Stream program,'c','open read'
labl. = 0; n = 0
do while Lines(program) > 0
prog = Linein(program)
select
when left(prog,2) = '--' then
nop
when right(prog,1) = ':' then do
label = left(prog,length(prog)-1)
end
when left(prog,10) = 'procedure ' then do
if pos('expose',prog) > 0 then do
x = substr(prog,18)
do while x <> ''
parse var x expo x
n = n+1; labl.proc.n = label; labl.stem.n = expo
end
end
end
otherwise
nop
end
end
labl.0 = n
call Stream program,'c','close'
tot = 0
crossref = 'Crossref.txt'
call Stream crossref,'c','open write replace'
call Sortproc
call lineout crossref,'STEMS BY PROCEDURE'
head1 = left('Procedure',15) left('Stem',5)
head2 = copies('-',length(head1))
call lineout crossref,head2
call lineout crossref,head1
call lineout crossref,head2
do i = 1 to n
call lineout crossref,left(labl.proc.i,15) labl.stem.i
tot = tot+1
end
call lineout crossref,head2
call lineout crossref,''
tot = tot+6
call Sortstem
call lineout crossref,'PROCEDURES BY STEM'
head1 = left('Stem',5) left('Procedure',15)
call lineout crossref,head2
call lineout crossref,head1
call lineout crossref,head2
do i = 1 to n
call lineout crossref,labl.stem.i left(labl.proc.i,15)
tot = tot+1
end
call lineout crossref,head2
tot = tot+5
call Stream crossref,'c','close'
if verbose then do
say tot 'lines'
say 'Done'
say
end
return
Sortproc:
-- Sort by procedure and stem
procedure expose labl.
n = labl.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
m = (l+r)%2; i = l; j = r
a = labl.proc.m; b = labl.stem.m
do until i > j
do i = i
if labl.proc.i > a then
leave
if labl.proc.i = a then
if labl.stem.i >= b then
leave
end
do j = j by -1
if labl.proc.j < a then
leave
if labl.proc.j = a then
if labl.stem.j <= b then
leave
end
if i <= j then do
t = labl.proc.i; labl.proc.i = labl.proc.j; labl.proc.j = t
t = labl.stem.i; labl.stem.i = labl.stem.j; labl.stem.j = t
i = i+1; j = j-1
end
end
if j-l < r-i then do
if i < r then do
s = s+1; sl.s = i; sr.s = r
end
r = j
end
else do
if l < j then do
s = s+1; sl.s = l; sr.s = j
end
l = i
end
end
end
return
Sortstem:
-- Sort by stem and procedure
procedure expose labl.
n = labl.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
m = (l+r)%2; i = l; j = r
a = labl.stem.m; b = labl.proc.m
do until i > j
do i = i
if labl.stem.i > a then
leave
if labl.stem.i = a then
if labl.proc.i >= b then
leave
end
do j = j by -1
if labl.stem.j < a then
leave
if labl.stem.j = a then
if labl.proc.j <= b then
leave
end
if i <= j then do
t = labl.stem.i; labl.stem.i = labl.stem.j; labl.stem.j = t
t = labl.proc.i; labl.proc.i = labl.proc.j; labl.proc.j = t
i = i+1; j = j-1
end
end
if j-l < r-i then do
if i < r then do
s = s+1; sl.s = i; sr.s = r
end
r = j
end
else do
if l < j then do
s = s+1; sl.s = l; sr.s = j
end
l = i
end
end
end
return
-- Module Run.rex - 1 Apr 2025
-- REXX Preprocessor and Executor
-- Usage: rexx|regina run <your program> <your arguments>
Main:
-- Main program flow
-- Trap conditions
signal on halt name Abend
signal on notready name Abend
signal on syntax name Abend
call Time('r')
-- Get various parameters
parse arg program parms
parse version version
-- Program to process, suffix 'rex' assumed if not specified
if Pos('.',program) = 0 then
program = program'.rex'
-- Get search path from Windows environment
-- Current folder and main folder '\Rex' assumed
p = Value(path,,environment)
n = 1; srce.n = ''; search = ''
do while p <> ''
parse var p a';'p
if Translate(Left(a,5)) = '\REX\' then do
n = n+1; srce.n = a'\'; search = search a
end
end
srce.0 = n; search = Strip(search)
-- Find program to process
do n = 1 to srce.0 until s <> ''
rex = srce.n||program
s = Stream(rex,'c','query exists')
end
if s = '' then
call Abend 'P'
n1 = 0; nr = 0; stat. = 0; sn = 0
-- Open output program to generate
runner = 'Runner.rex'
stampr = Stream(rex,'c','query timestamp')
stampr = Date('n',Left(stampr,10),'i') Right(stampr,8)
call Stream runner,'c','open write replace'
-- Write source info
call Lineout runner,'--' rex
nr = nr+1
-- Process source
le = Length(rex)
call Stream rex,'c','open read'
do while Lines(rex) = 1
n1 = n1+1; rexline = Linein(rex)
-- Something to include? Verb 'include' assumed
if Translate(Word(rexline,1)) = 'INCLUDE' then do
-- Find source to include. Suffix '.inc' assumed
do n = 1 to srce.0 until s <> ''
inc = srce.n||Word(rexline,2)'.inc'
s = Stream(inc,'c','query exists')
end
if s = "" then
call Abend 'I'
-- Saved on
stampi = Stream(inc,'c','query timestamp')
stampi = Date('n',Left(stampi,10),'i') Right(stampi,8)
-- Write header
call Lineout runner,'--' inc
nr = nr+1
-- Save change parameters
parm = 0
do wrd = 3 to Words(rexline)
parm = parm+1; parm.parm = Word(rexline,wrd)
end
parm.0 = parm; eerste = 1; n2 = 0
-- Process file to include
le = Max(Length(inc),le)
call Stream inc,'c','open read'
do while Lines(inc) = 1
n2 = n2+1
incline = Linein(inc)
-- Verb 'default' assumed for text replacement
if Translate(Word(incline,1)) = 'DEFAULT' then do
-- Add default change parameters
do wrd = 2 to Words(incline)
tmp = Word(incline,wrd)
parse var tmp change '=' .
if Pos(change,rexline) = 0 then do
parm = parm+1; parm.parm = Word(incline,wrd)
end
end
parm.0 = parm
end
else do
-- Write change parameters
if eerste = 1 then do
if parm.0 > 0 then do
changes = ''
do prm = 1 to parm.0
changes = changes parm.prm
end
call Lineout runner,'-- Replace 'changes
nr = nr+1
end
eerste = 0
end
-- Process changes
do prm = 1 to parm.0
parse var parm.prm change '=' in
incline = Changestr(change,incline,in)
end
-- Write line from include
if Pos('ooRexx',version) > 0 then do
call Lineout runner,incline
nr = nr+1
end
else do
if Left(incline,2) <> '::' then do
call Lineout runner,incline
nr = nr+1
end
end
end
end
-- Write some footers
call Stream inc,'c','close'
call Lineout runner,'--' inc
nr = nr+1
-- Save stats
sn = sn+1; stat.include.sn = inc; stat.stamp.sn = stampi; stat.Lines.sn = n2
end
else do
-- Write original source
if Pos('ooRexx',version) > 0 then do
call Lineout runner,rexline
nr = nr+1
end
else do
if Left(rexline,2) <> '::' then do
call Lineout runner,rexline
nr = nr+1
end
end
end
end
-- Source processing done
call Stream rex,'c','close'
-- Write stats
se = '--' Copies('-',le+27)
call Lineout runner,''
call Lineout runner,se
call Lineout runner,'--' Left('Summary',le) 'Lines' Left('Timestamp',20)
call Lineout runner,se
call Lineout runner,'--' Left(rex,le) Right(n1,5) Right(stampr,20)
nr = nr+5
do i = 1 to sn
call Lineout runner,'--' Left(stat.include.i,le) Right(stat.Lines.i,5) Right(stat.stamp.i,20)
nr = nr+1
end
nr = nr+3
call Lineout runner,se
call Lineout runner,'--' Left('Runner.rex',le) Right(nr,5) Right(Date() Time(),20)
call Lineout runner,se
call Stream runner,'c','close'
-- Run the generated program. Regina and ooRexx precoded.
select
when Pos('Regina',version) > 0 then
'regina' runner parms
when Pos('ooRexx',version) > 0 then
'rexx' runner parms
end
exit
Abend:
-- Condition handling specific for the preprocessor
arg type
say
signal off halt
signal off notready
signal off syntax
parse version version
say 'Rexx :' version
parse source . . source
say 'Source :' source
say 'Progr :' program
select
when type = 'P' then do
say 'Search :' search
say 'Error : Program not found'
end
when type = 'I' then do
say 'Incl :' Word(rexline,2)
say 'Search :' search
say 'Error : Include not found'
end
otherwise do
cc = Condition('c'); dd = Condition('d')
select
when cc = 'HALT' then
cc = 'Program interrupted'
when cc = 'NOTREADY' then
cc = 'Program or Include is in use'
when cc = 'NOVALUE' then
cc = 'Variable has no value'
when cc = 'SYNTAX' then
cc = 'Runtime error'
otherwise
cc = ''
end
if cc <> '' then
say 'Signal :' cc
if Datatype(rc) = 'NUM' then
if rc > 0 then
say 'Error :' rc Errortext(rc)
if dd <> '' then
if dd <> 'SIGINT' then
say 'Reason :' dd
end
end
exit
-- Module Calc.rex - 1 Apr 2025
-- REXX calculator
-- Regina|Rexx calc and play at the REXX prompt
IgnoreError16:
include Settings
do forever
call Charout, 'REXX '
pull command
if command = '' then
leave
interpret command
say
end
return
include Abend
include Complex
include Constants
include Functions
include Numbers
include Polynomial
include Rational
include Roots
include Sequences
-- Module Demo1.rex - 22 Feb 2025
-- Demo having only required modules included
Main:
-- Main program flow
include Settings
say version; say 'Complex arithmetic'; say
a = '1 2'; b = '3 4'; c = '5 6'; d = '7 8'
say 'VALUES'
say 'a =' Crect2form(a)
say 'b =' Crect2form(b)
say 'c =' Crect2form(c)
say 'd =' Crect2form(d)
say
say 'BASICS'
say 'a+b =' Crect2form(Cadd(a,b))
say 'a+b+c+d =' Crect2form(Cadd(a,b,c,d))
say 'a-b =' Crect2form(Csub(a,b))
say 'a-b-c-d =' Crect2form(Csub(a,b,c,d))
say 'a*b =' Crect2form(Cmul(a,b))
say 'a*b*c*d =' Crect2form(Cmul(a,b,c,d))
say 'a/b =' Crect2form(Cdiv(a,b))
say 'a/b/c/d =' Crect2form(Cdiv(a,b,c,d))
say '-a =' Crect2form(Cneg(a))
say '1/a =' Crect2form(Cinv(a))
say
say 'BONUS'
say 'Argument(a) =' Carg(a)
say 'Conjugate(a) =' Crect2form(Cconj(a))
say 'ImagPart(a) =' Cim(a)
say 'Modulus(a) =' Cmod(a)
say 'Polar(a) =' Cpol2form(Cpol(a))
say 'RealPart(a) =' Cre(a)
say
say 'FORMULA'
say 'a^2-2ab+3c-4ad^4+5 = ',
Crect2form(Cadd(Cpow(a,2),Cmul(-2,a,b),Cmul(3,c),Cmul(-4,a,Cpow(d,4)),5))
exit
include Complex
include Functions
include Constants
include Abend
-- Module Demo2.rex - 22 Feb 2025
-- Demo having the whole package included
Main:
-- Main program flow
include Settings
say version; say 'Rational arithmetic'; say
a = '1 2'; b = '-3 4'; c = '5 -6'; d = '-7 -8'; e = 3; f = 1.666666666
say 'VALUES'
say 'a =' Rlst2form(a)
say 'b =' Rlst2form(b)
say 'c =' Rlst2form(c)
say 'd =' Rlst2form(d)
say 'e =' e
say 'f =' f
say
say 'BASICS'
say 'a+b =' Rlst2form(Radd(a,b))
say 'a+b+c+d =' Rlst2form(Radd(a,b,c,d))
say 'a-b =' Rlst2form(Rsub(a,b))
say 'a-b-c-d =' Rlst2form(Rsub(a,b,c,d))
say 'a*b =' Rlst2form(Rmul(a,b))
say 'a*b*c*d =' Rlst2form(Rmul(a,b,c,d))
say 'a/b =' Rlst2form(Rdiv(a,b))
say 'a/b/c/d =' Rlst2form(Rdiv(a,b,c,d))
say '-a =' Rlst2form(Rneg(a))
say '1/a =' Rlst2form(Rinv(a))
say
say 'COMPARE'
say 'a<b =' Rlt(a,b)
say 'a<=b =' Rle(a,b)
say 'a=b =' Req(a,b)
say 'a>=b =' Rge(a,b)
say 'a>b =' Rgt(a,b)
say 'a<>b =' Rne(a,b)
say
say 'BONUS'
say 'Abs(c) =' Rlst2form(Rabs(c))
say 'Equal(a,b) =' Req(a,b)
say 'Float(b) =' Rfloat(b)
say 'Neg(d) =' Rlst2form(Rneg(d))
say 'Power(a,e) =' Rlst2form(Rpower(a,e))
say 'Rational(f) =' Rlst2form(Rrat(f))
say
say 'FORMULA'
say 'a^2-2ab+3c-4ad^4+5 = ',
Rlst2form(Radd(Rpower(a,2),Rmul(-2,a,b),Rmul(3,c),Rmul(-4,a,Rpower(d,4)),5))
exit
include Math
-- Module Model1.rex - 23 Feb 2025
-- Template for your own math playground
Main:
-- Main program flow
include Settings
-- Your code...
exit
include Math
-- Module Abend.inc - 11 Apr 2025
-- Condition/abend handler and debugging tool
-- Also used for argument error trapping
-- and display of the program call stack
Abend:
-- Condition and abend handler
-- Disable signals
Trace off
signal off halt
signal off notready
signal off novalue
signal off syntax
-- Condition info
parse version version!; parse source . . source!
s! = Strip(Sourceline(sigl)); c! = Condition('c'); d! = Condition('d')
-- Source info
if rc <> 16 then do
say
say 'Rexx :' version!
say 'Source :' source!
end
say 'Line :' sigl s!
-- Variables
call GetVariables
call ShowVariables
-- Condition message
select
when d! = 'ARGUMENT' then
c! = 'Argument outside domain, invalid or missing'
when d! = 'STACK' then
c! = 'Program call stack display forced by user'
when c! = 'HALT' then
c! = 'Program interrupted by user'
when c! = 'NOTREADY' then
c! = 'File does not exist or is in use by another app'
when c! = 'NOVALUE' then
c! = 'Variable has no value'
when c! = 'SYNTAX' then
c! = 'Runtime error'
otherwise
c! = ''
end
-- Additional info
if rc <> 16 then do
say 'Digits :' Digits()
if c! <> '' then
say 'Signal :' c!
if d! <> 'ARGUMENT' & d! <> 'STACK' then do
if Datatype(rc) = 'NUM' then
if rc > 0 then
say 'Error :' rc Errortext(rc)
if d! <> '' then
if d! <> 'SIGINT' then
say 'Reason :' d!
end
end
say
-- Force program call stack display
signal on novalue name IgnoreError16
say IgnoreError16
return
Debug:
-- Debugging info
-- Show relevant info
s! = Strip(Sourceline(sigl)); d! = Condition('d')
say
say 'Line :' sigl s!
call GetVariables
call ShowVariables
return
GetVariables:
-- Variable collector
-- Collect variables from source line
v!. = 0
s! = Upper(s!)
s! = Translate(s!," ","+-*|<>,;=/\%()'")
do i! = 1 to Words(s!)
w! = Word(s!,i!)
if Symbol(w!) = 'VAR' then do
call Variable
if Pos('.',w!) > 0 then do
t! = Translate(w!," ",".")
do j! = 2 to Words(t!)
w! = Word(t!,j!)
if Symbol(w!) = 'VAR' then
call Variable
end
end
end
end
return
Variable:
-- Variable saver
-- Save variable
do k! = 1 to v!.0
if w! = v!.k! then
leave
end
if k! > v!.0 then do
v!.k! = w!; v!.0 = k!
end
return
ShowVariables:
-- Variable displayer
-- Show values
do i! = 1 to v!.0
v! = v!.i!; a! = Value(v!)
if d! = 'ARGUMENT' then
say 'Arg :' v! '=' '"'a!'"'
else
say 'Var :' v! '=' '"'a!'"'
end
return
-- Module Complex.inc - 22 Mar 2025
-- Complex numbers arithmetic, functions and tools
-- Numbers are coded as string 'real imaginary'
-- Examples '1 2' = 1+2i, '0 1' = i, '1' = 1
Cabs:
-- Absolute value (modulus, magnitude)
-- |z|
procedure expose glob.
arg xx
-- Formula
return Cmod(xx)
Cadd:
-- Addition
-- z1+z2+z3+...
procedure
if Arg() = 0 then say argument
-- Add all arguments
do n = 1 to Arg()
xx = Arg(n) 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument n
if \ Datatype(xi,'n') then say argument n
if n = 1 then do
zr = xr; zi = xi
end
else do
zr = zr+xr; zi = zi+xi
end
end
return (zr) (zi)
Carccos:
-- Inverse cosine
-- -i*Ln(z+Sqrt(z^2-1))
procedure expose glob.
arg xx
-- Fast
numeric digits Digits()+1
if Ceq(xx,-1) then
return Pi()
if Ceq(xx,-0.5) then
return Tau()/3
if Ceq(xx,0) then
return Halfpi()
if Ceq(xx,0.5) then
return Pi()/3
if Ceq(xx,1) then
return 0
-- Formula
if Ceq(xx,Cneg(I())) then
return (Halfpi()) (Ln(Sqrt(2)+1))
if Ceq(xx,I()) then
return (Halfpi()) (Ln(Sqrt(2)-1))
return Cmul(-1,I(),Cln(Cadd(xx,Csqrt(Csub(Csquare(xx),1)))))
Carccot:
-- Inverse cotangent
-- -i*Ln((z+i)/(z-i))/2
procedure expose glob.
arg xx
-- Fast
numeric digits Digits()+1
if Ceq(xx,-1) then
return -0.25*Pi()
if Ceq(xx,0) then
return Halfpi()
if Ceq(xx,1) then
return 0.25*Pi()
-- Formula
return Cmul(-0.5,I(),Cln(Cdiv(Cadd(xx,I()),Csub(xx,I()))))
Carccsc:
-- Inverse cosecant
-- i*Ln(Sqrt(1-1/z^2)-i/z)
procedure expose glob.
arg xx
-- Fast
numeric digits Digits()+1
if Ceq(xx,-2) then
return -Pi()/6
if Ceq(xx,-1) then
return -Halfpi()
if Ceq(xx,1) then
return Halfpi()
if Ceq(xx,2) then
return Pi()/6
-- Formula
return Cmul(I(),Cln(Csub(Csqrt(Csub(1,Cinv(Csquare(xx)))),Cdiv(I(),xx))))
Carcosh:
-- Inverse cosine hyperbolic
-- Ln(z+Sqrt(z^2-1))
procedure expose glob.
arg xx
-- Fast
numeric digits Digits()+1
if Ceq(xx,-1) then
return (0) (Pi())
if Ceq(xx,-0.5) then
return (0) (Tau()/3)
if Ceq(xx,0) then
return (0) (Halfpi())
if Ceq(xx,0.5) then
return (0) (Pi()/3)
if Ceq(xx,1) then
return 0
-- Formula
if Ceq(xx,Cneg(I())) then
return Cln(Cmul(-1,I(),1+Sqrt(2)))
if Ceq(xx,I()) then
return Cln(Cmul(I(),1+Sqrt(2)))
return Cln(Cadd(xx,Csqrt(Csub(Csquare(xx),1))))
Carcoth:
-- Inverse cotangent hyperbolic
-- Ln((1+z)/(1-z))/2
procedure expose glob.
arg xx
-- Fast
numeric digits Digits()+1
if Ceq(xx,0) then
return (0) (Halfpi())
if Ceq(xx,Cneg(I())) then
return (0) (0.25*Pi())
if Ceq(xx,I()) then
return (0) (-0.25*Pi())
-- Formula
return Cmul(0.5,Cln(Cdiv(Cadd(xx,1),Csub(xx,1))))
Carcsch:
-- Inverse cosecant hyperbolic
-- Ln(1/z+Sqrt(1+1/z^2))
procedure expose glob.
arg xx
-- Fast
numeric digits Digits()+1
if Ceq(xx,-1) then
return Ln(Sqrt(2)-1)
if Ceq(xx,1) then
return Ln(Sqrt(2)+1)
if Ceq(xx,Cmul(-2,I())) then
return (0) (Pi()/6)
if Ceq(xx,Cneg(I())) then
return (0) (Halfpi())
if Ceq(xx,I()) then
return (0) (-Halfpi())
if Ceq(xx,Cmul(2,I())) then
return (0) (-Pi()/6)
-- Formula
a = Cinv(xx); b = Csquare(a)
return Cln(Cadd(a,Csqrt(Cadd(b,1))))
Carcsec:
-- Inverse secant
-- -i*Ln(i*Sqrt(1-1/z^2)+1/z)
procedure expose glob.
arg xx
-- Fast
numeric digits Digits()+1
if Ceq(xx,-2) then
return Tau()/3
if Ceq(xx,-1) then
return 0
if Ceq(xx,1) then
return 0
if Ceq(xx,2) then
return Pi()/3
-- Formula
if Ceq(xx,Cneg(I())) then
return (Halfpi()) (Ln(Sqrt(2)-1))
if Ceq(xx,I()) then
return (Halfpi()) (Ln(Sqrt(2)+1))
return Cmul(-1,I(),Cln(Cadd(Cmul(I(),Csqrt(Csub(1,Cinv(Csquare(xx))))),Cinv(xx))))
Carcsin:
-- Inverse sine
-- i*Ln(Sqrt(1-z^2)-i*z)
procedure expose glob.
arg xx
-- Fast
numeric digits Digits()+1
if Ceq(xx,-1) then
return -Halfpi()
if Ceq(xx,-0.5) then
return -Pi()/6
if Ceq(xx,0) then
return 0
if Ceq(xx,0.5) then
return Pi()/6
if Ceq(xx,1) then
return Halfpi()
-- Formula
if Ceq(xx,Cneg(I())) then
return (0) (Ln(Sqrt(2)-1))
if Ceq(xx,I()) then
return (0) (Ln(Sqrt(2)+1))
return Cmul(I(),Cln(Csub(Csqrt(Csub(1,Csquare(xx))),Cmul(I(),xx))))
Carctan:
-- Inverse tangent
-- Ln((1+i*z)/(1-i*z))/(2i)
procedure expose glob.
arg xx
-- Fast
numeric digits Digits()+1
if Ceq(xx,-1) then
return -0.25*Pi()
if Ceq(xx,0) then
return 0
if Ceq(xx,1) then
return 0.25*Pi()
-- Formula
a = Cmul(I(),xx)
return Cdiv(Cln(Cdiv(Cadd(1,a),Csub(1,a))),I(),2)
Carg:
-- Argument (phase)
-- Arctan2(Re(z),Im(z))
procedure expose glob.
arg xx; xx = xx 0; parse var xx xr xi .
-- Formula
numeric digits Digits()+1
return Arctan2(xr,xi)
Carsech:
-- Inverse secant hyperbolic
-- Ln(1/z+Sqrt(1-1/z^2))
procedure expose glob.
arg xx
-- Fast
numeric digits Digits()+1
if Ceq(xx,-2) then
return (0) (Tau()/3)
if Ceq(xx,-1) then
return (0) (Pi())
if Ceq(xx,1) then
return 0
if Ceq(xx,2) then
return (0) (Pi()/3)
-- Formula
if Ceq(xx,Cneg(I())) then
return (Ln(Sqrt(2)+1)) (Cmul(0.5,Pi()))
if Ceq(xx,I()) then
return (Ln(Sqrt(2)+1)) (Cmul(-0.5,Pi()))
a = Cinv(xx); b = Csquare(a)
return Cln(Cadd(a,Csqrt(Csub(b,1))))
Carsinh:
-- Inverse sine hyperbolic
-- Ln(z+Sqrt(z^2+1))
procedure expose glob.
arg xx
-- Fast
numeric digits Digits()+1
if Ceq(xx,-1) then
return Ln(Sqrt(2)-1)
if Ceq(xx,0) then
return 0
if Ceq(xx,1) then
return Ln(Sqrt(2)+1)
if Ceq(xx,Cneg(I())) then
return (0) (-Halfpi())
if Ceq(xx,Cmul(-0.5,I())) then
return (0) (-Pi()/6)
if Ceq(xx,Cmul(0.5,I())) then
return (0) (Pi()/6)
if Ceq(xx,I()) then
return (0) (Halfpi())
-- Formula
return Cln(Cadd(xx,Csqrt(Cadd(Csquare(xx),1))))
Cartanh:
-- Inverse tangent hyperbolic
-- Ln((1+z)/(1-z))/2
procedure expose glob.
arg xx
-- Fast
numeric digits Digits()+1
if Ceq(xx,0) then
return 0
if Ceq(xx,Cneg(I())) then
return (0) (-0.25*Pi())
if Ceq(xx,I()) then
return (0) (0.25*Pi())
-- Formula
return Cmul(0.5,Cln(Cdiv(Cadd(1,xx),Csub(1,xx))))
Ccbrt:
-- Cubic root
-- z^(1/3)
procedure expose glob.
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 0
if Ceq(xx,1) then
return 1
-- Formula
numeric digits Digits()+2
zz = Cmul(Cbrt(Cmod(xx)),Cexp(Cmul(I(),Carg(xx),1/3)))
return zz
Cconj:
-- Conjugate
-- Re(z) -Im(z)
procedure
arg xx; xx = xx 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument
if \ Datatype(xi,'n') then say argument
-- Formula
return (xr) (-xi)
Ccos:
-- Cosine
-- Cos(Re(z))Cosh(Im(z)) -Sin(Re(z))Sinh(Im(z))
procedure expose glob.
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 1
-- Formula
numeric digits Digits()+1
return (Cos(xr)*Cosh(xi)) (-Sin(xr)*Sinh(xi))
Ccosh:
-- Cosine hyperbolic
-- Cosh(Re(z))Cos(Im(z)) Sinh(Re(z))Sin(Im(z))
procedure expose glob.
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 1
-- Formula
numeric digits Digits()+1
return (Cosh(xr)*Cos(xi)) (Sinh(xr)*Sin(xi))
Ccot:
-- Cotangent
-- Cos(z)/Sin(z)
procedure expose glob.
arg xx
-- Formula
numeric digits Digits()+1
return Cdiv(Ccos(xx),Csin(xx))
Ccoth:
-- Cotangent hyperbolic
-- Cosh(z)/Sinh(z)
procedure expose glob.
arg xx
-- Formula
numeric digits Digits()+1
return Cdiv(Ccosh(xx),Csinh(xx))
Ccsc:
-- Cosecant
-- 1/Sin(z)
procedure expose glob.
arg xx
-- Formula
numeric digits Digits()+1
return Cinv(Csin(xx))
Ccsch:
-- Cosecant hyperbolic
-- 1/Sinh(z)
procedure expose glob.
arg xx
-- Formula
numeric digits Digits()+1
return Cinv(Csinh(xx))
Ccube:
-- Cube
-- z^3
procedure
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 0
if Ceq(xx,1) then
return 1
-- Formula
numeric digits Digits()+1
r2 = xr*xr; r3 = r2*xr; i2 = xi*xi; i3 = i2*xi
return (r3-3*xr*i2) (3*r2*xi-i3)
Cdiv:
-- Division
-- z1/z2/z3/...
procedure
if Arg() = 0 then say argument
-- Divide first argument by all other ones
numeric digits Digits()+1
do n = 1 to Arg()
xx = Arg(n) 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument n
if \ Datatype(xi,'n') then say argument n
if n = 1 then do
zr = xr; zi = xi
end
else do
if Ceq(xx,0) then say argument n
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)
Ceq:
-- Equal?
procedure
arg xx,yy; xx = xx 0; yy = yy 0; parse var xx xr xi .; parse var yy yr yi .
if \ Datatype(xr,'n') then say argument
if \ Datatype(xi,'n') then say argument
if \ Datatype(yr,'n') then say argument
if \ Datatype(yi,'n') then say argument
-- z1 = z2?
return (xr=yr & xi=yi)
Ceval:
-- Evaluation polynomial with real coefficients
procedure
arg xx,yy; yy = yy 0; parse var yy yr yi .
if xx = '' then say argument
-- Horner's scheme
zz = 0 0
numeric digits Digits()+2
do n = 1 to Words(xx)
w = Word(xx,n)
zz = Cadd(Cmul(zz,yy),w)
end
return zz
Cexp:
-- Exponential
-- e^Re(z)*Cos(Im(z)) e^Re(z)*Sin(Im(z))
procedure expose glob.
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 1
if Ceq(xx,1) then
return E()
-- Formula
numeric digits Digits()+1
a = Exp(xr)
return (a*Cos(xi)) (a*Sin(xi))
Cim:
-- Imaginary part
-- Im(z)
procedure
arg xx; xx = xx 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument
if \ Datatype(xi,'n') then say argument
-- Formula
return (xi)
Cinv:
-- Inversion
-- 1/z
procedure
arg xx
-- Formula
numeric digits Digits()+1
return Cdiv(1,xx)
Cln:
-- Natural logarithm
-- Ln|z| Arg(z)
procedure expose glob.
arg xx
if Ceq(xx,0) then say argument
-- Formula
numeric digits Digits()+1
return (Ln(Cmod(xx))) (Carg(xx))
Cmod:
-- Modulus (absolute value, magnitude)
-- |z|
procedure expose glob.
arg xx; xx = xx 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument
if \ Datatype(xi,'n') then say argument
-- Formula
numeric digits Digits()+1
return Sqrt(xr*xr+xi*xi)
Cmul:
-- Multiplication
-- z1*z2*z3*...
procedure
if Arg() = 0 then say argument
-- Multiply all arguments
numeric digits Digits()+1
do n = 1 to Arg()
xx = Arg(n) 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument n
if \ Datatype(xi,'n') then say argument n
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)
Cne:
-- Not equal
-- z1 <> z2?
procedure
arg xx,yy
-- Formula
return \ Ceq(xx,yy)
Cneg:
-- Negation
-- -Re(z) -Im(z)
procedure
arg xx; xx = xx 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument
if \ Datatype(xi,'n') then say argument
-- Formula
return (-xr) (-xi)
Cnorm:
-- Normalization
-- Re(z)/1 Im(z)/1
procedure
arg xx; xx = xx 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument
if \ Datatype(xi,'n') then say argument
-- Formula
return (xr/1) (xi/1)
Complex:
-- Are all arguments in C?
procedure
do n = 1 to Arg()
xx = Arg(n) 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument n
if \ Datatype(xi,'n') then say argument n
end
return 1
Cpol:
-- Rectangular -> Polar
-- Re(z) Im(z) -> |z| Arg(z)
procedure expose glob.
arg xx
-- Formula
numeric digits Digits()+1
return (Cmod(xx)) (Carg(xx))
Cpol2form:
-- Polar -> Formula
procedure
arg xx; xx = xx 0; parse var xx xm xa .
if \ Datatype(xm,'n') then say argument
if \ Datatype(xa,'n') then say argument
-- Compose 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
Cpow:
-- Integer power
-- z^n, n in Z
procedure
arg xx,yy
if \ Datatype(yy,'w') then say argument
-- Fast
if Ceq(xx,0) then
return 0
if Ceq(xx,1) then
return 0
if Ceq(yy,0) then
return 1
if Ceq(yy,1) then
return xx
-- Calculate power by repeated divide or multiply
numeric digits Digits()+2
if yy < 0 then do
zz = Cinv(xx)
do Abs(yy)-1
zz = Cdiv(zz,xx)
end
end
else do
zz = xx
do yy-1
zz = Cmul(zz,xx)
end
end
return zz
Cpower:
-- Complex power
-- e^(w*Ln(z)), w in R or C
procedure expose glob.
arg xx,yy
-- Fast
if Ceq(xx,0) then
return 0
if Ceq(xx,1) then
return 0
if Ceq(yy,0) then
return 1
if Ceq(yy,1) then
return xx
-- Formula
numeric digits Digits()+1
return Cexp(Cmul(yy,Cln(xx)))
Cqtrt:
-- Quartic root
-- z^(1/4)
procedure expose glob.
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 0
if Ceq(xx,1) then
return 1
-- Formula
numeric digits Digits()+2
zz = Cmul(Cbrt(Cmod(xx)),Cexp(Cmul(I(),Carg(xx),0.25)))
return zz
Cquartic:
-- Quartic
-- z^4
procedure
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 0
if Ceq(xx,1) then
return 1
-- Formula
numeric digits Digits()+1
-- Formula
numeric digits Digits()+1
r2 = xr*xr; r3 = r2*xr; r4 = r2*r2; i2 = xi*xi; i3 = i2*xi; i4 = i2*i2
return (r4-6*r2*i2+i4) (4*r3*xi-4*xr*i3)
Cre:
-- Real part
-- Re(z)
procedure
arg xx; xx = xx 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument
if \ Datatype(xi,'n') then say argument
-- Formula
return xr
Crect:
-- Polar -> Rectangular
-- |z| Arg(z) -> Re(z) Im(z)
procedure expose glob.
arg xx; xx = xx 0; parse var xx xm xa .
if \ Datatype(xm,'n') then say argument
-- Formula
numeric digits Digits()+1
return (xm*Cos(xa)) (xm*Sin(xa))
Crect2form:
-- Rectangular -> Formula
procedure
arg xx; xx = xx 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument
if \ Datatype(xi,'n') then say argument
-- Compose 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
Cround:
-- Round to specified decimals
procedure
arg xx,yy; xx = xx 0; parse var xx xr xi .
if yy = '' then
yy = 0
-- Formula
return (Round(xr,yy)) (Round(xi,yy))
Csci:
-- Convert to scientific format
procedure
arg xx; xx = xx 0; parse var xx xr xi .
-- Formula
return Sci(xr) Sci(xi)
Csec:
-- Secant
-- 1/Cos(z)
procedure expose glob.
arg xx
-- Fast
if Ceq(xx,0) then
return 1
-- Formula
numeric digits Digits()+1
return Cinv(Ccos(xx))
Csech:
-- Secant hyperbolic
-- 1/Cosh(z)
procedure expose glob.
arg xx
-- Fast
if Ceq(xx,0) then
return 1
-- Formula
numeric digits Digits()+1
return Cinv(Ccosh(xx))
Csin:
-- Sine
-- Sin(Re(z))Cosh(Im(z)) Cos(Re(z))Sinh(Im(z))
procedure expose glob.
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 0
-- Formula
numeric digits Digits()+1
return (Sin(xr)*Cosh(xi)) (Cos(xr)*Sinh(xi))
Csinh:
-- Sine hyperbolic
-- Sinh(Re(z))Cos(Im(z)) Cosh(Re(z))Sin(Im(z))
procedure expose glob.
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 0
-- Formula
numeric digits Digits()+1
return (Sinh(xr)*Cos(xi)) (Cosh(xr)*Sin(xi))
Csqrt:
-- Square root
-- z^(1/2)
procedure expose glob.
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 0
if Ceq(xx,1) then
return 1
-- Formula
numeric digits Digits()+2
m = Cmod(xx)
a = Round(m+xr,Digits()-2); b = Round(m-xr,Digits()-2)
if xi < 0 then
s = -1
else
s = 1
r = Sqrt(0.5*a); i = Sqrt(0.5*b)*s
return (r) (i)
Csquare:
-- Square
-- z^2
procedure
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 0
if Ceq(xx,1) then
return 1
-- Formula
xr2 = xr*xr; xi2 = xi*xi
return (xr2-xi2) (2*xr*xi)
Cstd:
-- Convert to standard format
procedure
arg xx; xx = xx 0; parse var xx xr xi .
-- Formula
return Std(xr) Std(xi)
Csub:
-- Subtraction
-- z1-z2-z3-...
procedure
if Arg() = 0 then say argument
-- Subtract second and following arguments from the first one
numeric digits Digits()+1
do n = 1 to Arg()
xx = Arg(n) 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument n
if \ Datatype(xi,'n') then say argument n
if n = 1 then do
zr = xr; zi = xi
end
else do
zr = zr-xr; zi = zi-xi
end
end
return (zr) (zi)
Ctan:
-- Tangent
-- Sin(z)/Cos(z)
procedure expose glob.
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 0
-- Formula
numeric digits Digits()+1
return Cdiv(Csin(xx),Ccos(xx))
Ctanh:
-- Tangent hyperbolic
-- Sinh(z)/Cosh(z)
procedure expose glob.
arg xx; xx = xx 0; parse var xx xr xi .
-- Fast
if Ceq(xx,0) then
return 0
-- Formula
numeric digits Digits()+1
return Cdiv(Csinh(xx),Ccosh(xx))
Czero:
-- Zero?
procedure
arg xx; xx = xx 0; parse var xx xr xi .
if \ Datatype(xr,'n') then say argument
if \ Datatype(xi,'n') then say argument
-- z1 = 0?
return (xr=0 & xi=0)
-- Module Constants.inc - 22 Mar 2025
-- Mathematical constants like Pi, E, Phi, i and many more
Apery:
-- Apery constant
procedure
-- Fast
if Digits() < 111 then
return 1.2020569031595942853997381615114499907649862923404988817922715553418382057863130901864558736093352581461991578
-- Wedeniwski recurring
numeric digits Digits()+2
-- Term k = 0
f10 = 1; f20 = 1; f21 = 1; f32 = 2; f43 = 6; p = 12463; s = 1
zz = 0; v = 0
numeric fuzz 2
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
return zz/24
Artin:
-- Artin constant
procedure
-- Fast
return 0.373955813619202288054728054346416415111629248606150042094742802417350182040028082344304317087250568981603
Backhouse:
-- Backhouse constant
procedure
-- Fast
return 1.45607494858268967139959535111654355765317837484713154027070243741400150626538989559964531940186030910992
Bernstein:
-- Bernstein constant
procedure
-- Fast
return 0.28016949902386913303643649123067200004248213981236
Bloch:
-- Bloch constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.471861653452681784874468793611316149077012621739443243631460266888006805241859656902448655624594840993
-- Formula
return Sqrt((Sqrt(3)-1)*0.5)*Gamma(1/3)*Gamma(11/12)/Gamma(0.25)
Bronze:
-- Bronze ratio constant
-- Positive root of x^2-3x-1
procedure
-- Fast
if Digits() < 111 then
return 3.3027756377319946465596106337352479731256482869226231063552265281135834741465052226023095410092453588367570910
-- Formula
return 0.5*(3+Sqrt(13))
Brun:
-- Brun constant
procedure
-- Fast
return 1.902160583104
Cahen:
-- Cahen constant
procedure
-- Fast
if Digits() < 111 then
return 0.64341054628833802618225430775756476328658786026823950598703092030749277646183261084844089555046343195405372901
-- Sylvester
numeric digits Digits()+2
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
return zz
Capacity:
-- Logarithmic capacity of the unit disk constant
procedure
-- Fast
return 0.5901702995080481130226689702792442936168583174407236497579321997021520903603578974892293080979039771
Catalan:
-- Catalan constant
procedure
-- Fast
if Digits() < 111 then
return 0.91596559417721901505460351493238411077414937428167213426649811962176301977625476947935651292611510624857442262
-- Broadhurst
numeric digits Digits()+2
numeric fuzz 2
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
return 3*s1-2*s2
Chaitin:
-- Chaitin constant
procedure
-- Fast
return 0.0078749969978123844
Champernowne:
-- Champernowne constant
procedure
-- Fast
if Digits() < 111 then
return 0.123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616
-- Concatenate integers
p = Digits()+4
zz = '0.'
do n = 1 while Length(zz) <= p
zz = zz||n
end
return zz
Conway:
-- Conway constant
-- Real root of x^71-x^69-2x^68...-6x^2+3x-6
procedure
-- Fast
if Digits() < 111 then
return 1.3035772690342963912570991121525518907307025046594048757548613906285508878524615571268157668644252255534713930471
-- Polynomial and derivatives
p =,
'1 0 -1 -2 -1 2 2 1 -1 -1 -1 -1',
'-1 2 5 3 -2 -10 -3 -2 6 6',
'1 9 -3 -7 -8 -8 10 6 8 -5',
'-12 7 -7 7 1 -3 10 1 -6 -2',
'-10 -3 2 9 -3 14 -8 0 -7 9',
'3 -4 -10 -7 12 7 2 -12 -4 -2',
'5 0 1 -7 7 -4 12 -6 3 -6'
p1 = Pdif(p); p2 = Pdif(p1)
-- Dynamic precision
d = Digits()+2
do n = 1 while d > 4
d.n = d; d = Trunc(0.44*d)
end
d.n = 4
-- Halley
zz = 1.3
do k = n by -1 to 1
numeric digits d.k
f = Peval(p,zz); f1 = Peval(p1,zz); f2 = Peval(p2,zz)
zz = zz - (2*f*f1) / (2*f1*f1-f*f2)
end
return zz
Copeland:
-- Copeland-Erdos constant
procedure
-- Fast
return 0.23571113171923293137414347535961677173798389971011031071091131271311371391491511571631671731791811911
Devicci:
-- DeVicci constant
-- Positive root of 4x^8-28x^6-7x^4+16x^2+16
procedure
-- Fast
if Digits() < 111 then
return 1.0074347568842793760982535952310991419256901141136697702349637985711523132802867779625205514746359239420763739328
-- Polynomial and derivatives
p = '4 0 -28 0 -7 0 16 0 16'
p1 = Pdif(p); p2 = Pdif(p1)
-- Dynamic precision
d = Digits()+2
do n = 1 while d > 4
d.n = d; d = Trunc(0.38*d)
end
d.n = 4
-- Halley
zz = 1.0
do k = n by -1 to 1
numeric digits d.k
f = Peval(p,zz); f1 = Peval(p1,zz); f2 = Peval(p2,zz)
zz = zz-(2*f*f1)/(2*f1*f1-f*f2)
end
return zz
Dottie:
-- Dottie constant
-- Root of Cos(x)-x
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.73908513321516064165531208767387340401341175890075746496568063577328465488354759459937610693176653184980124664
-- Dynamic precision
d = Digits()+2
do n = 1 while d > 4
d.n = d; d = Trunc(0.36*d)
end
d.n = 4
-- Halley
zz = 0.74
do k = n by -1 to 1
numeric digits d.k
c = Cos(zz); s = Sin(zz); f = c-zz; f1 = -s-1; f2 = -c
zz = zz-(2*f*f1)/(2*f1*f1-f*f2)
end
return zz
Dubois:
-- Second Dubois-Reymond constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.1945280494653251136152137302875039065901577852759236620435639112612868980395288816921562425395608973868765806327394
-- Formula
return (E()**2-7)*0.5
E:
-- Euler constant
procedure expose glob.
-- Fast
p = Digits()
if p < 111 then
return 2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919
if glob.e.p <> '' then
return glob.e.p
-- Taylor
numeric digits Digits()+2
numeric fuzz 2
zz = 2; t = 1
do n = 2 until zz = v
v = zz
t = t/n; zz = zz+t
end
glob.e.p = zz
return zz
Embree:
-- Embree-Trefethen constant
procedure
-- Fast
return 0.70258
Erdos1:
-- Erdos-Borwein constant
procedure
-- Fast
if Digits() < 111 then
return 1.6066951524152917637833015231909245804805796715057564357780795536914184207434866905657118016701555758970454290631544131
-- Series
numeric digits Digits()+2
zz = 0
numeric fuzz 2
do n = 1 until zz = v
v = zz
a = 2**n; zz = zz+(1/a**n)*(a+1)/(a-1)
end
return zz
Erdos2:
-- Erdos-Tenenbaum-Ford constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.086071332055934206887573098776922677760591109530333173492020236665422635814622879799380534602528768071633655969112
-- Formula
return 1-(1+Ln(Ln(2)))/Ln(2)
Euler:
-- Euler-Mascheroni constant
procedure expose glob.
-- Fast
p = Digits()
if p < 111 then
return 0.57721566490153286060651209008240243104215933593992359880576723488486772677766467093694706329174674951463144725
if glob.euler.p <> '' then
return glob.euler.p
-- Brent McMillan
numeric digits Digits()+2
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
glob.euler.p = s/v
return glob.euler.p
Feigenbaum1:
-- Feigenbaum first constant
procedure
-- Fast
return 4.66920160910299067185320382046620161725818557747576863274565134300413433021131473713868974402394801381716
Feigenbaum2:
-- Feigenbaum second constant
procedure
-- Fast
return 2.50290787509589282228390287321821578638127137672714997733619205677923546317959020670329964974643383412959
Feller:
-- Feller-Tornier constant
procedure
-- Fast
return 0.66131704946962233528976584627411853328547528983291635498090562622662503174312230494226174078428187
Foias:
-- Foias constant
procedure
-- Fast
return 1.18745235112650105459548015839651935121569268158586035301010412619878041872352540738702465760608657943378
Fraction:
-- First continued fraction constant
procedure
-- Fast
return 0.697774657964007982006790592551752599486658262998021232368630082816530852764641112996965654182676568723982
Fransen:
-- Fransen-Robertson constant
procedure
-- Fast
return 2.80777024202851936522150118655777293230808592093019829122005480959710088912190166551018530816819663814187
Gauss:
-- Gauss constant
procedure
-- Fast
if Digits() < 111 then
return 0.83462684167407318628142973279904680899399301349034700244982737010368199270952641186969116035127532412906785035
-- Formula
return 1/Agmean(1,Sqrt(2))
Gelfond1:
-- Gelfond constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 23.14069263277926900572908636794854738026610624260021199344504640952434235069045278351697199706754921967595270
-- Formula
return Power(E(),Pi())
Gelfond2:
-- Gelfond-Schneider constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 2.665144142690225188650297249873139848274211313714659492835979593364920446178705954867609180005196416941989364
-- Formula
return Power(2,Sqrt(2))
Gieseking:
-- Gieseking constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 1.014941606409653625021202554274520285941689307530299792017489106776597476258244022136470354228256694945861828
-- Formula
return (Trigamma(1/3)-Trigamma(2/3))/(4*Sqrt(3))
Glaisher:
-- Glaisher-Kinkelin constant
procedure
-- Fast
return 1.28242712910062263687534256886979172776768892732500119206374002174040630885882646112973649195820237
Golden:
-- Golden ratio constant
-- Root of x^2-x-1
procedure
-- Fast
if Digits() < 111 then
return 1.618033988749894848204586834365638117720309179805762862135448622705260462818902449707207204189391137484754088
-- Formula
return (Sqrt(5)+1)*0.5
Goldenangle:
-- Golden angle constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 2.399963229728653322231555506633613853124999011058115042935112750731307338239438790779962060660583963731372963
-- Formula
return Pi()*(3-Sqrt(5))
Golomb:
-- Golomb constant
procedure
-- Fast
return 0.624329988543550870992936383100837244179642620180529286973551902495638088855113254462460276195539868869
Gompertz:
-- Gompertz constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.5963473623231940743410784993692793760741778601525487815734849104823272191148744174704304970936127603442370347484286
-- Taylor
numeric digits Digits()+2
zz = 0; s = 1; f = 1
numeric fuzz 2
do n = 1 until zz = v
v = zz
s = -s; f = f*n; zz = zz+s/(n*f)
end
numeric fuzz
return -E()*(Euler()+zz)
Hafner:
-- Hafner-Sarnak-McCurley constant
procedure
-- Fast
return 0.353236371854995984543516550432682011280164778566690446416085942814238325002669003483672078334335498967
Halfpi:
-- Pi/2
procedure expose glob.
-- Fast
if Digits() < 111 then
return 1.570796326794896619231321691639751442098584699687552910487472296153908203143104499314017412671058533991074043
-- Formula
return 0.5*Pi()
Heath:
-- Heath-Brown-Moroz constant
procedure
-- Fast
return 0.00131764115485317810981735232251358595125073432329525167879254742178602344409610895090834
Hermite:
-- Second Hermite constant
procedure
-- Fast
if Digits() < 111 then
return 1.154700538379251529018297561003914911295203502540253752037204652967955344605866691387430791171499050450417428
-- Formula
return 2/Sqrt(3)
I:
-- Imaginary unit
procedure
-- Fast
return (0 1)
Kepler:
-- Kepler-Bouwkamp constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.11494204485329620070104015746959874283079533720086351684402339651896601282535305117794077248498583699376347675
d = Digits()
numeric digits d*3
-- Optimized asymptotic
zz = 0; v = 0
do k = 1 to 1000 until zz = v
v = zz
numeric fuzz
a = 2*k; b = Zeta(a); c = 2**a
numeric fuzz Digits()-d-2
zz = zz+((c-1)/a)*b*(b-1-1/c)
end
numeric fuzz
return Exp(-2*zz)
Khinchin:
-- Khinchin constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 2.6854520010653064453097148354817956938203822939944629530511523455572188595371520028011411749318476979951534659
-- Asymptotic
numeric digits Digits()+2
y1 = 0
do n = 1 until y1 = v
v = y1
y2 = 0
do k = 1 to 2*n-1
y2 = y2+(-1)**(k+1)/k
end
numeric fuzz
y1 = y1+((Zeta(2*n)-1)/n)*y2
numeric fuzz 2
end
numeric fuzz
return Exp(y1/Ln(2))
Komornik:
-- Komornik-Loreti constant
procedure
-- Fast
return 1.78723165018296593301327489033700838533793140296181099778478147050555749175060568699131001863407533302
Landau1:
-- Landau-Ramanujan constant
procedure
-- Fast
return 0.7642236535892206629906987312500923281167905413934095147216866737496146416587328588384015050131312337
Landau2:
-- Landau constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.543258965342976706952728295300613231138863293758356988955732569100434687015307837312852127102259710857533437902199
-- Formula
return Power(2,5/3)*Pi()**2/(3*Gamma(1/3)**3)
Laplace:
-- Laplace limit constant
procedure
-- Fast
return 0.66274341934918158097474209710925290705623354911502241752039253499097185308651127724965480259895818168
Lebesgue:
-- Lebesgue constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.98943127383114695174164880901886671492420140609111104828412243264437253158457865463463298314018955793304417328
-- Series
numeric digits Digits()+2
zz = 0
do n = 0 until zz = v
v = zz
numeric fuzz
zz = zz+(Lambda(2*n+2)-1)/(2*n+1)
numeric fuzz 2
end
numeric fuzz
a = Pi()**2
return 8*zz/a+4*(2*Ln(2)+Euler())/a
Lemniscate:
-- Lemniscate constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 2.62205755429211981046483958989111941368275495143162316281682170380079058707041425023029553296142909344613575
-- Formula
return Pi()/Agmean(1,Sqrt(2))
Levy1:
-- Levy-Khinchin constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 1.186569110415625452821722975947237120568356536472054335954254298652809632056254443300348301108486875946639263747175
-- Formula
return Pi()**2/(12*Ln(2))
Levy2:
-- Second Levy constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 3.275822918721811159787681882453843863608475525982374149405198924190723215644960355181277540479174529492698526243402
-- Formula
return Exp(Levy1())
Lieb:
-- Lieb constant
procedure
-- Fast
if Digits() < 111 then
return 1.539600717839002038691063414671886548393604670053671669382939537290607126141155588516574388228665400600556570147028
-- Formula
return 8/(3*Sqrt(3))
Ln10:
-- Natural log of 10 constant
procedure expose glob.
-- Fast
p = Digits()
if p < 111 then
return 2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840
if glob.ln10.p <> '' then
return glob.ln10.p
-- Weisstein
numeric digits Digits()+2
zz = 0
do k = 0 until zz = v
v = zz
k8 = 8*k; zz = zz+(729/(k8+1)+162/(k8+2)+81/(k8+3)+9/(k8+5)+2/(k8+6)+1/(k8+7))/6561**k
end
zz = 2*zz/729; glob.ln10.p = zz
return zz
Ln2:
-- Natural log of 2 constant
procedure expose glob.
-- Fast
p = Digits()
if p < 111 then
return 0.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641868754200148102
if glob.Ln2.p <> '' then
return glob.Ln2.p
-- Weisstein
numeric digits Digits()+2
zz = 0
do k = 0 until zz = v
v = zz
k18 = 18*k; zz = zz+(2187/(k18+1)-1458/(k18+3)-729/(k18+4)-81/(k18+7)+54/(k18+9)+27/(k18+10)+3/(k18+13)-2/(k18+15)-1/(k18+16))/(-19683)**k
end
zz = zz/2187; glob.Ln2.p = zz
return zz
Ln4:
-- Natural log of 4 constant
procedure expose glob.
-- Formula
return 2*Ln2()
Loch:
-- Loch constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.970270114392033925740256019210010833781284704785161286610350529931254199891737048036212674908029026469241589522939
-- Formula
return 6*Ln(2)*Ln(10)/Pi()**2
Magicangle:
-- Magic angle constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.95531661812450927816385710251575775424341469501000549095969812932191204590397645538739160258562807342160190353
-- Formula
return Arccos(1/Sqrt(3))
Maxnumber:
-- Maximum number allowed
procedure
-- Value
return 9E999999999
Meissel:
-- Meissel-Mertens constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.2614972128476427837554268386086958590515666482611992061920642139249245108973682097141426314342466510516177288764860
-- Series
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
return Euler()+zz
Mills:
-- Mills constant
procedure
-- Fast
return 1.30637788386308069046861449260260571291678458515671364436805375996643405376682659882150140370119739570729
Mrb:
-- MRB constant
procedure
-- Fast
return 0.187859642462067120248517934054273230055903094900138786172004684089477231564660213703296654433107496903842
Nielsen:
-- Nielsen-Ramanujan constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.822467033424113218236207583323012594609474950603399218867779114685003735201600436916814450309879352652002159
-- Formula
return Pi()**2/12
Niven:
-- Niven constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 1.705211140105367764288551453434508160762027651653469099994284906547313192168122491934244132100871001797653827048
-- Series
numeric digits Digits()+2
zz = 0
do k = 2 to 1000 until zz = v
v = zz
numeric fuzz
zz = zz+1-1/Zeta(k)
numeric fuzz 2
end
numeric fuzz
return zz+1
Omega:
-- Omega constant
-- Root of x*e^x-1
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.56714329040978387299996866221035554975381578718651250813513107922304579308668456669321944696175229455763802497
-- Dynamic precision
d = Digits()+2
do n = 1 while d > 4
d.n = d; d = Trunc(0.40*d)
end
d.n = 4
-- Halley
zz = 0.57
do k = n by -1 to 1
numeric digits d.k
a = Exp(zz); b = a*zz-1
zz = zz-b/(a*(zz+1)-((zz+2)*b/(2*zz+2)))
end
return zz
Paperfolding:
-- Paper folding constant
procedure
-- Fast
if Digits() < 111 then
return 0.8507361882018672603677977605320666044113994930827106477281682610318301584593194453485459826421939239960918042677191
-- Definition
numeric digits Digits()+2
numeric fuzz 2
zz = 0
do n = 0 until zz = v
v = zz
zz = zz+8**(2**n)/(2**(2**(n+2))-1)
end
return zz
Parabolic:
-- Universal parabolic constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 2.295587149392638074034298049189490387597832203638583483929975346644109662684133126684094426237897615591753662
-- Formula
return Ln(Sqrt(2)+1)+Sqrt(2)
Pi:
-- Pi constant
procedure expose glob.
-- Fast
p = Digits()
if p < 111 then
return 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148087
if glob.pi.p <> '' then
return glob.pi.p
-- Chudnovsky
numeric digits Digits()+2
if p < 201 then do
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; z = 1; g = Sqrt(0.5); n = 1
do until z = v
v = z
numeric fuzz
x = (z+g)*0.5; g = Sqrt(z*g)
numeric fuzz 2
zz = zz-n*(x-z)**2; n = n+n; z = x
end
numeric fuzz
zz = z*z/zz
end
glob.pi.p = zz
return zz
Plastic:
-- Plastic ratio constant
-- Real root of x^3-x-1
procedure
-- Fast
if Digits() < 111 then
return 1.324717957244746025960908854478097340734404056901733364534015050302827851245547594054699347981787280329910921
-- Polynomial and derivatives
p = '1 0 -1 -1'
p1 = Pdif(p); p2 = Pdif(p1)
-- Dynamic precision
d = Digits()+2
do n = 1 while d > 4
d.n = d; d = Trunc(0.36*d)
end
d.n = 4
-- Halley
zz = 1.3
do k = n by -1 to 1
numeric digits d.k
f = Peval(p,zz); f1 = Peval(p1,zz); f2 = Peval(p2,zz)
zz = zz-(2*f*f1)/(2*f1*f1-f*f2)
end
return zz
Porter:
-- Porter constant
procedure
-- Fast
return 1.46707807943397547289779848470722995344990332241488777739968581761660674432904480843036932751117401521266
Prouhet:
-- Prouhet-Thue-Morse constant
procedure
-- Fast
if Digits() < 111 then
return 0.41245403364010759778336136825845528308947837445576955757337941534879359236578258896380454048621213339625636645
-- Infinite product
numeric digits Digits()+2
zz = 1; v = 1
do n = 0
zz = zz*(1-1/2**(2**n))
if zz = v
then leave
v = zz
end
return (2-zz)*0.25
Ramanujan:
-- Ramanujan constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 262537412640768743.9999999999992500725971981856888793538563373369908627075374103782106479101186073129511813462
-- Formula
return Exp(Pi()*Sqrt(163))
Recifibo:
-- Reciprocal Fibonacci constant
procedure
-- Fast
if Digits() < 111 then
return 3.359885666243177553172011302918927179688905133731968486495553815325130318996683383615416216456790087297045342928854
-- Recurring
numeric digits Digits()+2
zz = 1; a = 0; b = 1
numeric fuzz 2
do n = 2 until zz = v
v = zz
c = a+b; zz = zz+1/c
a = b; b = c
end
return zz
Robbins:
-- Robbins constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.6617071822671762351558311332484135817464001357909536048089442294795846461385976313066524807681071201517097753107594
-- Formula
return (4+17*Sqrt(2)-6*Sqrt(3)-7*Pi())/105+(Ln(1+Sqrt(2)))*0.2+(Ln(2+Sqrt(3)))*0.4
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
if Digits() < 111 then
return 1.1762808182599175065440703384740350506934158065646952598301063470296883765485499620968301155818153946592071814
-- Polynomial and derivatives
p = '1 1 0 -1 -1 -1 -1 -1 0 1 1'
p1 = Pdif(p); p2 = Pdif(p1)
-- Dynamic precision
d = Digits()+2
do n = 1 while d > 4
d.n = d; d = Trunc(0.39*d)
end
d.n = 4
-- Halley
zz = 1.2
do k = n by -1 to 1
numeric digits d.k
f = Peval(p,zz); f1 = Peval(p1,zz); f2 = Peval(p2,zz)
zz = zz-(2*f*f1)/(2*f1*f1-f*f2)
end
return zz
Sierpinski:
-- Sierpinski constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 2.5849817595792532170658935873831711600880516518526309173215449879719320440011571202111177245270642830313440
-- Formula
return Pi()*Ln(Exp(2*Euler())/(2*Gauss()**2))
Silver:
-- Silver ratio constant
-- Positive root of x^2-2x-1
procedure
-- Fast
if Digits() < 111 then
return 2.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641572735013846
-- Formula
return Sqrt(2)+1
Soldner:
-- Soldner constant
procedure
-- Fast
return 1.45136923488338105028396848589202744949303228364801586309300455766242559575451783565953135771108682884
Somos:
-- Somos quadratic recurrence constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 1.661687949633594121295818922749950749964418635025068208189711168025609029826383727908369176411461167155281345509912
-- Definition
numeric digits Digits()+2
zz = 1; v = 0; a = 2
do n = 1
zz = zz*Power(n,1/a)
if zz = v
then leave
v = zz; a = 2*a
end
return zz
Sqrt2:
-- Square root of 2 constant
-- Real root of x^2-2
procedure
-- Fast
if Digits() < 111 then
return 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462
-- Dynamic precision
numeric digits Digits()+2
d = Digits()
do n = 1 while d > 4
d.n = d; d = Trunc(0.36*d)
end
d.n = 4
-- Halley
zz = 1.4
do k = n by -1 to 1
numeric digits d.k
z2 = zz*zz; zz = zz-2*zz*(z2-2)/(3*z2+2)
end
return zz
Sqrt3:
-- Square root of 3 constant
-- Real root of x^2-3
procedure
-- Fast
if Digits() < 111 then
return 1.7320508075688772935274463415058723669428052538103806280558069794519330169088000370811461867572485756756261414
-- Dynamic precision
numeric digits Digits()+2
d = Digits()
do n = 1 while d > 4
d.n = d; d = Trunc(0.36*d)
end
d.n = 4
-- Halley
zz = 1.7
do k = n by -1 to 1
numeric digits d.k
z2 = zz*zz; zz = zz-2*zz*(z2-3)/(3*z2+3)
end
return zz
Sqrt5:
-- Square root of 5 constant
-- Real root of x^2-5
procedure
-- Fast
if Digits() < 111 then
return 2.2360679774997896964091736687312762354406183596115257242708972454105209256378048994144144083787822749695081762
-- Dynamic precision
numeric digits Digits()+2
d = Digits()
do n = 1 while d > 4
d.n = d; d = Trunc(0.36*d)
end
d.n = 4
-- Halley
zz = 2.2
do k = n by -1 to 1
numeric digits d.k
z2 = zz*zz; zz = zz-2*zz*(z2-5)/(3*z2+5)
end
return zz
Stephens:
-- Stephens constant
procedure
-- Fast
return 0.57595996889294543964316337549249669250651396717649236360064079866537255169886852843640987209172618
Supergolden:
-- Super golden ratio constant
-- Real root of x^3-x^2-1
procedure
-- Fast
if Digits() < 111 then
return 1.465571231876768026656731225219939108025577568472285701643183111249262996685017840478125801194909270064382456
-- Polynomial and derivatives
p = '1 -1 0 -1'
p1 = Pdif(p); p2 = Pdif(p1)
-- Dynamic precision
d = Digits()+2
do n = 1 while d > 4
d.n = d; d = Trunc(0.36*d)
end
d.n = 4
-- Halley
zz = 1.5
do k = n by -1 to 1
numeric digits d.k
f = Peval(p,zz); f1 = Peval(p1,zz); f2 = Peval(p2,zz)
zz = zz-(2*f*f1)/(2*f1*f1-f*f2)
end
return zz
Taniguchi:
-- Taniguchi constant
procedure
-- Fast
return 0.678234491917391978035538279482894814096332239189440103036460415964983370740123233213762122933484616888328
Tau:
-- Tau constant
-- 2pi
procedure expose glob.
-- Fast
if Digits() < 111 then
return 6.283185307179586476925286766559005768394338798750211641949889184615632812572417997256069650684234135964296173
-- Formula
return 2*Pi()
Tetranacci:
-- Tetranacci constant
-- Root of x^4-x^3-x^2-x-1
procedure
-- Fast
if Digits() < 111 then
return 1.927561975482925304261905861736622168698554255163384727146647038009666062297815559149818253461890653254266934313
-- Polynomial and derivatives
p = '1 -1 -1 -1 -1'
p1 = Pdif(p); p2 = Pdif(p1)
-- Dynamic precision
d = Digits()+2
do n = 1 while d > 4
d.n = d; d = Trunc(0.38*d)
end
d.n = 4
-- Halley
zz = 1.9
do k = n by -1 to 1
numeric digits d.k
f = Peval(p,zz); f1 = Peval(p1,zz); f2 = Peval(p2,zz)
zz = zz-(2*f*f1)/(2*f1*f1-f*f2)
end
return zz
Tribonacci:
-- Tribonacci constant
-- Root of x^3-x^2-x-1
procedure
-- Fast
if Digits() < 111 then
return 1.8392867552141611325518525646532866004241787460975922467787586394042032220819664257384354194283070141419798269
-- Polynomial and derivatives
p = '1 -1 -1 -1'
p1 = Pdif(p); p2 = Pdif(p1)
-- Dynamic precision
d = Digits()+2
do n = 1 while d > 4
d.n = d; d = Trunc(0.38*d)
end
d.n = 4
-- Halley
zz = 1.8
do k = n by -1 to 1
numeric digits d.k
f = Peval(p,zz); f1 = Peval(p1,zz); f2 = Peval(p2,zz)
zz = zz-(2*f*f1)/(2*f1*f1-f*f2)
end
return zz
Twinprimes:
-- Twin primes constant
procedure
-- Fast
return 0.660161815846869573927812110014555778432623360284733413319448423335405642304495277143760031413839867911779
Vanderpauw:
-- Van der Pauw constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 4.5323601418271938096276829457166668101718614677237955841860165479406009537213051022590838796040160896530664627078
-- Formula
return Pi()/Ln(2)
Viswanath:
-- Viswanath constant
procedure
-- Fast
return 1.1319882487943
Wallis:
-- Wallis constant
-- Real root of x^3-2x-5
procedure
-- Fast
if Digits() < 111 then
return 2.094551481542326591482386540579302963857306105628239180304128529045312189983483667146267281777157757860839521
-- Polynomial and derivatives
p = '1 0 -2 -5'
p1 = Pdif(p); p2 = Pdif(p1)
-- Dynamic precision
d = Digits()+2
do n = 1 while d > 4
d.n = d; d = Trunc(0.38*d)
end
d.n = 4
-- Halley
zz = 2.1
do k = n by -1 to 1
numeric digits d.k
f = Peval(p,zz); f1 = Peval(p1,zz); f2 = Peval(p2,zz)
zz = zz-(2*f*f1)/(2*f1*f1-f*f2)
end
return zz
Weierstrass:
-- Weierstrass constant
procedure expose glob.
-- Fast
if Digits() < 111 then
return 0.4749493799879206503325046363279829685595493732172029822833310248645579291748838602742756412505021444189037849426240
-- Formula
return Power(2,1.25)*Sqrt(Pi())*Exp(Pi()*0.125)/Gamma(0.25)**2
Zscore:
-- Z-score 97.5 percentile constant
procedure
-- Fast
return 1.95996398454005423552459443052055152795555007786954839847695264636163527414488266779825470949281420601799
-- Module Functions.inc - 11 Apr 2025
-- Standard and advanced mathematical functions
-- This module supports only real arguments and results
Ackermann:
-- Ackermann's function
procedure
arg xx,yy
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
if \ Datatype(yy,'w') then say argument
if yy < 0 then say argument
-- Fast
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
-- Definition
if yy = 0 then
return Ackermann(xx-1,1)
else
return Ackermann(xx-1,Ackermann(xx,yy-1))
Agmean:
-- Arithmetic geometric mean
-- AGM
procedure
arg xx,yy
if \ Datatype(xx,'n') then say argument
if xx <= 0 then say argument
if \ Datatype(yy,'n') then say argument
if yy < 0 then say argument
-- Fast
if yy = 0 then
return 0
if xx = yy then
return xx
-- Series
numeric digits Digits()+1
vx = xx+1
do until xx = vx
vx = xx; vy = yy
xx = (vx+vy)*0.5; yy = Sqrt(vx*vy)
end
return xx
Aliquot:
-- Aliquot function
-- Sum of proper divisors
procedure
arg xx
-- Formula
return Divisor(xx,1)-xx
Alog10:
-- Antilog base 10
-- 10^x
procedure expose glob.
arg xx
-- Formula
numeric digits Digits()+1
return Power(10,xx)
Amean:
-- Arithmetic mean
-- AM
procedure
nn = Arg()
if nn = 0 then say argument
-- Cf definition
numeric digits Digits()+1
zz = 0
do n = 1 to nn
xx = Arg(n)
if \ Datatype(xx,'n') then say argument
zz = zz+xx
end
return zz/nn
Arccos:
-- Inverse cosine
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if Abs(xx) > 1 then say argument
-- Reflect
numeric digits Digits()+1
if xx < 0 then
return Pi()-Arccos(-xx)
-- Fast
if xx = 0 then
return Halfpi()
if xx = 0.5 then
return Pi()/3
if xx = 1 then
return 0
-- Formula
if xx < 0.71 then
return Halfpi()-Arcsin(xx)
if xx < 0.81 then do
numeric digits Digits()+1
return Arctan(Sqrt(1-xx*xx)/xx)
end
else do
numeric digits Digits()-Xpon(1-xx)
return Arcsin(Sqrt(1-xx*xx))
end
Arccot:
-- Inverse cotangent
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Reflect
numeric digits Digits()+1
if xx < 0 then
return Pi()-Arccot(-xx)
-- Fast
if xx = 0 then
return Halfpi()
if xx = 1 then
return 0.25*Pi()
-- Formula
if xx < 0.40 then
return Arccos(xx/Sqrt(xx*xx+1))
else
return Arctan(1/xx)
Arccsc:
-- Inverse cosecant
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if Abs(xx) < 1 then say argument
-- Reflect
if xx < 0 then
return -Arccsc(-xx)
-- Fast
numeric digits Digits()+1
if xx = 1 then
return Halfpi()
if xx = 2 then
return Pi()/6
-- Formula
return Arcsin(1/xx)
Arcosh:
-- Inverse cosine hyperbolic
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx < 1 then say argument
-- Fast
if xx = 1 then
return 0
-- Formula
numeric digits Digits()-(xx<1.1)*Xpon(xx-1)+2
return Ln(xx+Sqrt(xx*xx-1))
Arcoth:
-- Inverse cotangent hyperbolic
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx <= 1 then say argument
-- Formula
numeric digits Digits()+Xpon(xx)+1
return 0.5*Ln((xx+1)/(xx-1))
Arcsch:
-- Inverse cosecant hyperbolic
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx = 0 then say argument
-- Formula
numeric digits Digits()+Max(Xpon(xx),0)+3
zz = 1/xx
return Ln(zz+Sqrt(zz*zz+1))
Arcsec:
-- Inverse secant
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if Abs(xx) < 1 then say argument
-- Reflect
numeric digits Digits()+1
if xx < 0 then
return Pi()-Arcsec(-xx)
-- Fast
if xx = 1 then
return 0
if xx = 2 then
return Pi()/3
-- Formula
return Arccos(1/xx)
Arcsin:
-- Inverse sine
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if Abs(xx) > 1 then say argument
-- Reflect
if xx < 0 then
return -Arcsin(-xx)
-- Fast
numeric digits Digits()+2
if xx = 0 then
return 0
if xx = 0.5 then
return Pi()/6
if xx = 1 then
return Halfpi()
-- Formula
if xx > 0.80 then do
if xx > 0.90 then
numeric digits Digits()-Xpon(1-xx)
return Halfpi()-Arcsin(Sqrt(1-xx*xx))
end
-- Taylor
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
return zz
Arctan:
-- Inverse tangent
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Reflect
if xx < 0 then
return -Arctan(-xx)
-- Fast
numeric digits Digits()+3
if xx = 0 then
return 0
if xx = 1 then
return 0.25*Pi()
-- Formula
if xx > 3 then do
xx = 1/xx
return Halfpi()-Arcsin(xx/Sqrt(xx*xx+1))
end
-- Reduce argument towards zero
r = 2-(xx<2)-(xx<0.70)
do r
xx = xx/(1+Sqrt(xx*xx+1))
end
-- Taylor
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
-- Undo reduce
return 2**r*zz
Arctan2:
-- Inverse tangent right quadrant
procedure expose glob.
arg xx,yy
if \ Datatype(xx,'n') then say argument
if \ Datatype(yy,'n') then say argument
-- Fast
numeric digits Digits()+1
if yy = 0 then
return 0
if xx = 0 then
return 0.5*Sign(yy)*Pi()
-- Formula
if xx > 0 then
return Arctan(yy/xx)
if yy < 0 then
return Arctan(yy/xx)-Pi()
else
return Arctan(yy/xx)+Pi()
Arsech:
-- Inverse secant hyperbolic
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx <= 0 then say argument
if xx > 1 then say argument
-- Fast
if xx = 1 then
return 0
-- Formula
numeric digits Digits()-(xx>0.90)*Xpon(1-xx)+4
zz = 1/xx
return Ln(zz+Sqrt(zz*zz-1))
Arsinh:
-- Inverse sine hyperbolic
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Reflect
if xx < 0 then
return -Arsinh(-xx)
-- Fast
if xx = 0 then
return 0
-- Formula
numeric digits Digits()-(xx<1)*Xpon(xx)+2
if xx > 0.50 then
return Ln(xx+Sqrt(xx*xx+1))
-- Taylor
t = xx; zz = t; x2 = xx*xx
numeric fuzz 2
do n = 2 by 2 until zz = v
v = zz
t = -t*x2*(n-1)*(n-1)/(n*n+n); zz = zz+t
end
return zz
Artanh:
-- Inverse tangent hyperbolic
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if Abs(xx) >= 1 then say argument
-- Fast
if xx = 0 then
return 0
-- Reflect
if xx < 0 then
return -Artanh(-xx)
-- Formula
numeric digits Digits()-Xpon(1-xx)+1
if xx > 0.40 then
return 0.5*Ln((1+xx)/(1-xx))
-- Taylor
numeric digits Digits()+2
t = xx; zz = t; x2 = xx*xx
numeric fuzz 2
do n = 3 by 2 until zz = v
v = zz
t = t*x2*(n-2)/n; zz = zz+t
end
return zz
Beta:
-- Beta
procedure expose glob.
arg xx,yy
if \ Datatype(xx,'n') then say argument
if \ Datatype(yy,'n') then say argument
-- Formula
numeric digits Digits()+1
return Gamma(xx)*Gamma(yy)/Gamma(xx+yy)
Base10:
-- Base n -> 10
procedure
arg xx,yy
if xx = '' then say argument
xx = Upper(xx)
if \ Datatype(yy,'w') then say argument
if yy < 2 then say argument
if yy > 36 then say argument
-- Fast
if yy = 2 then
return X2d(B2x(xx))+0
if yy = 16 then
return X2d(xx)+0
-- Convert
b = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; l = Length(xx)
zz = 0
do i = 1 to l
d = Pos(Substr(xx,i,1),b)-1
if d = -1 | d >= yy then say argument
zz = zz*yy+d
end
return zz
Basenn:
-- Base 10 -> n
procedure
arg xx,yy
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
if \ Datatype(yy,'w') then say argument
if yy < 2 then say argument
if yy > 36 then say argument
-- Fast
if xx = 1 then
return xx
if yy = 2 then
return X2b(D2x(xx))+0
if yy = 16 then
return D2x(xx)
-- Convert
b = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
zz = ''
do while xx > 0
r = xx//yy; xx = xx%yy; zz = Substr(b,r+1,1)zz
end
return zz
Cbrt:
-- Cubic root
-- x^(1/3)
procedure
arg xx
if \ Datatype(xx,'n') then say argument
-- Fast
if xx = 0 then
return 0
if xx = 1 then
return 1
-- Sign
sx = Sign(xx); xx = Abs(xx)
-- Reduce argument to 1...1000
e = Xpon(xx); e = (e-(2*(e<0)))%3; f = -3*e; xx = Std(xx)'E'f
-- First guess 2 digits accurate
dd = Digits()+2
numeric digits 2
select
when xx < 8 then
zz = 1+(xx-1)/7
when xx < 27 then
zz = 2+(xx-8)/19
when xx < 64 then
zz = 3+(xx-27)/37
when xx < 125 then
zz = 4+(xx-64)/61
when xx < 216 then
zz = 5+(xx-125)/91
when xx < 343 then
zz = 6+(xx-216)/127
when xx < 512 then
zz = 7+(xx-343)/169
when xx < 729 then
zz = 8+(xx-512)/217
otherwise
zz = 9+(xx-729)/271
end
-- Dynamic precision
do n = 1 while dd > 4
d.n = dd; dd = Trunc(0.42*dd)
end
d.n = 4
-- Halley
do i = n to 1 by -1
numeric digits d.i
z3 = zz*zz*zz; zz = zz-zz*(z3-xx)/(2*z3+xx)
end
-- Undo reduce
return sx*zz'E'e
Ceil:
-- Ceiling
procedure
arg xx
if \ Datatype(xx,'n') then say argument
-- Formula
if Integer(xx) then
return xx
else
return Trunc(xx)+(xx>=0)
Comb:
-- Combination
-- Binomial coefficient
procedure expose glob.
arg xx,yy
if \ Datatype(xx,'w') then say argument
if \ Datatype(yy,'w') then say argument
if yy < 0 then say argument
if xx-yy < yy then
yy = xx-yy
-- Fast
if yy = 0 then
return 1
if glob.comb.xx.yy <> '' then
return glob.comb.xx.yy
-- Recurring loop
numeric digits Digits()+2
zz = xx
do i = 1 to yy-1
zz = zz*(xx-i)/(i+1)
end
glob.comb.xx.yy = zz
return zz
Cos:
-- Cosine
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Fast
if xx = 0 then
return 1
-- Reflect
if xx < 0 then
return Cos(-xx)
-- Reduce argument to 0...2pi
numeric digits Digits()+Max(Xpon(xx),0)+2
xx = xx//Tau()
-- Reduce argument to 0...pi/2
select
when xx < Halfpi() then
s = 1
when xx < Pi() then do
s = -1; xx = Pi()-xx
end
when xx < Pi()+Halfpi() then do
s = -1; xx = xx-Pi()
end
otherwise do
s = 1; xx = tau()-xx
end
end
-- Taylor
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
return s*zz
Cosh:
-- Cosine hyperbolic
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Reflect
if xx < 0 then
return Cosh(-xx)
-- Fast
if xx = 0 then
return 1
-- Taylor
numeric digits Digits()+1
if \ Integer(xx) & xx < 5 then do
xx = xx*xx; zz = 1; f = 1; v = 1
do n = 2 by 2 until zz = v
v = zz
f = f*xx/((n-1)*n); zz = zz+f
end
return zz
end
-- Formula
zz = Exp(xx)
return (zz*zz+1)/(2*zz)
Cot:
-- Cotangent
procedure expose glob.
arg xx
-- Formula
numeric digits Digits()+1
zz = Sin(xx)
if zz = 0 then say argument
return Cos(xx)/zz
Cotan:
-- Cotangent
procedure expose glob.
arg xx
-- Alias
return Cot(xx)
Coth:
-- Cotangent hyperbolic
procedure expose glob.
arg xx
if xx = 0 then say argument
-- Formula
numeric digits Digits()+1
return 1/Tanh(xx)
Csc:
-- Cosecant
procedure expose glob.
arg xx
-- Formula
numeric digits Digits()+1
zz = Sin(xx)
if zz = 0 then say argument
return 1/zz
Csch:
-- Cosecant hyperbolic
procedure expose glob.
arg xx
if xx = 0 then say argument
-- Formula
numeric digits Digits()+1
return 1/Sinh(xx)
Deg:
-- Radians -> Degrees
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Formula
numeric digits Digits()+1
return xx*180/Pi()
Dfact:
-- Double factorial
-- n!!
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
if glob.dfact.xx <> '' then
return glob.dfact.xx
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
-- Logarithmic derivative of Gamma
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx <= 0 & Integer(xx) then say argument
-- Formula
numeric digits Digits()+2
if xx = 0.125 then
return -Halfpi()-4*Ln(2)-(Pi()+Ln(Sqrt(2)+1)-Ln(Sqrt(2)-1))/Sqrt(2)-Euler()
if xx = 0.25 then
return -Halfpi()-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 & Integer(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
-- Reduce argument to a larger value
numeric digits Digits()+1
dd = Digits(); a = 0
do while xx < dd
a = a+1/xx; xx = xx+1
end
-- Series
zz = -0.5/xx; v = 0
do n = 2 by 2 until zz = v
v = zz
zz = zz+Zeta(1-n)/(xx**n)
end
-- Undo reduce
return Ln(xx)+zz-a
Digit:
-- Round to specified digits
procedure
arg xx,yy
if yy = '' then
yy = Digits()
-- Formula
return Round(Mant(xx),yy-1)'E'Xpon(xx)
Digitprod:
-- Digital product
-- Product of all digits
procedure
arg xx
if \ Datatype(xx,'w') 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 \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Formula
return 1+(xx-1)//9
Digitsum:
-- Digital sum
-- Sum of all digits
procedure
arg xx
if \ Datatype(xx,'w') 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
-- Som of all divisors^y
procedure expose glob. divi.
arg xx,yy
if yy = '' then
yy = 0
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
if \ Datatype(yy,'n') then say argument
numeric digits Digits()+2
select
-- Count divisors
when yy = 0 then do
n = 0
do while xx//2 = 0
n = n+1; xx = xx/2
end
zz = n+1
do i = 3 by 2 while i*i <= xx
n = 0
do while xx//i = 0
n = n+1; xx = xx/i
end
zz = zz*(n+1)
end
if xx > 2 then
zz = zz+zz
return zz
end
-- Get divisors and sum
when yy = 1 then do
d = Divisors(xx); zz = 0
do n = 1 to d
zz = zz+divi.n
end
end
-- Get divisors and sum integer power
when Integer(yy) then do
d = Divisors(xx); zz = 0
do n = 1 to d
zz = zz+divi.n**yy
end
end
-- Get divisors and sum real power
otherwise do
d = Divisors(xx); zz = 0
do n = 1 to d
zz = zz+Power(divi.n,yy)
end
end
end
return zz
Dxgamma:
-- First derivative of Gamma
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx <= 0 & Integer(xx) then say argument
-- Formula
dd = -Digits()
numeric digits -dd*2
a = 1'E'dd
return (Gamma(xx+a)-Gamma(xx))/a
Dxzeta:
-- First derivative of Zeta
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx = 1 then say argument
-- Formula
dd = Digits()
numeric digits dd+1
if xx = -2 then
return -Zeta(3)/(4*Pi()**2)
if xx = -1 then
return 1/12-Ln(Glaisher())
if xx < 0 & Even(xx) then
return (-1)**(-0.5*xx)*Fact(-xx)*Zeta(1-xx)/(2*(Tau())**-xx)
if xx = 0 then
return -0.5*Ln(Tau())
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
zz = 0
a = Power(2,xx); b = Ln(4); c = a-2
do n = 1 to 10000 until zz = v
v = zz
if n//2 = 0 then
t1 = 1
else
t1 = -1
zz = zz+(t1*a*Power(n,-xx))*(b+c*Ln(n))/(c*c)
end
end
else do
-- From derivative definition
numeric digits dd*4
e = -dd+dd%5; a = 1'E'e; zz = (Zeta(xx+a)-Zeta(xx))/a
end
return zz
Erf:
-- Error
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Asymptotic series
numeric digits Digits()+2
a = (2*xx*Exp(-xx*xx))/Sqrt(Pi()); b = 2*xx*xx
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
return a*zz
Erfc:
-- Error complementary
procedure expose glob.
arg xx
-- Formula
return 1-Erf(xx)
Eval:
-- Evaluation of an expression in x,y,z
procedure expose glob.
arg xx,x,y,z
if xx = '' then say argument
-- Evaluate
interpret 'return' xx
Even:
-- Is a number even?
procedure
arg xx
-- Formula
if Integer(xx) then
return \ Abs(xx//2)
else
return 0
Exp:
-- Exponential
-- e^x
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Fast
if xx = 0 then
return 1
if xx = 1 then
return E()
dd = Digits()
if glob.exp.xx.dd <> '' then
return glob.exp.xx.dd
-- Formula
numeric digits dd+3
if Integer(xx) then do
zz = E()**xx; glob.exp.xx.dd = zz
return zz
end
-- Reduce argument to -1/2...1/2
if Abs(xx) > 1 then do
a = Trunc(xx); xx = Frac(xx)
end
else
a = 0
if Abs(xx) > 0.5 then do
b = 1; xx = 0.5*xx
end
else
b = 0
-- Taylor
zz = 1; t = 1
do n = 1 until zz = v
v = zz
t = (t*xx)/n; zz = zz+t
end
-- Undo reduce
if b <> 0 then
zz = zz*zz
if a <> 0 then
zz = zz*E()**a
glob.exp.xx.dd = zz
return zz
Fact:
-- Integer factorial
-- n!
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
if xx < 2 then
return 1
if glob.fact.xx <> '' then
return glob.fact.xx
w = xx-1
-- Loop cf definition
if glob.fact.w = '' then do
zz = 1
do n = 2 to xx
zz = zz*n
end
glob.fact.xx = zz
end
-- Multiply
else
glob.fact.xx = glob.fact.w*xx
return glob.fact.xx
Factorial:
-- Real factorial
-- x!
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx < 0 & Integer(xx) then say argument
-- Formula
numeric digits Digits()+1
if Integer(xx) then
return Fact(xx)
else
return Gamma(xx+1)
Ffact:
-- Falling factorial
procedure expose glob.
arg xx,yy
if \ Datatype(xx,'w') then say argument
if \ Datatype(yy,'w') then say argument
if xx < 0 then say argument
-- Fast
if xx < 2 then
return 1
if yy = 0 then
return 1
if glob.ffact.xx.yy <> '' then
return glob.ffact.xx.yy
-- 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 \ Datatype(xx,'n') then say argument
-- Formula
if Integer(xx) then
return xx
else
return Trunc(xx)-(xx<0)
Frac:
-- Fractional part
procedure
arg xx
if \ Datatype(xx,'n') then say argument
-- Formula
return xx-xx%1
Gamma:
-- Gamma
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx < 1 & Integer(xx) then say argument
-- Formula
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
end
end
if xx > 0 then do
if Integer(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
end
end
d1 = Digits()
if d1 < 61 then do
-- Lanczos with predefined coefficients
numeric digits d1+2
-- Reflect
if xx < 0 then
return Pi()/(Gamma(1-xx)*Sin(Pi()*xx))
-- Reduce argument to 0.5...1.5
c = Trunc(xx); xx = xx-c
if xx < 0.5 then do
xx = xx+1; c = c-1
end
-- Series coefficients 1/Gamma(x) 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 reduce
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
d2 = Floor(1.5*d1); a = Floor(1.1*d1)
numeric digits d2
-- Series
s = 0
do k = 1 to a-1
s = s+((-1)**(k-1)*Power(a-k,k-0.5)*Exp(a-k))/(Fact(k-1)*(xx+k))
end
s = s+Sqrt(Tau()); zz = Power(xx+a,xx+0.5)*Exp(-a-xx)*s
end
return zz
Gcd:
-- Greatest common divisor
procedure
arg xx,yy
if \ Datatype(xx,'n') then say argument
xx = Abs(xx); yy = Abs(yy)
-- Fast
if yy = 0 then
return xx
-- Euclidian division
do until yy = 0
zz = xx//yy; xx = yy; yy = zz
end
return xx
Gmean:
-- Geometric mean
-- GM
procedure
nn = Arg()
if nn = 0 then say argument
-- Cf definition
numeric digits Digits()+1
zz = 1
do n = 1 to nn
xx = Arg(n)
if \ Datatype(xx,'n') then say argument n
if xx <= 0 then say argument n
zz = zz*xx
end
return Nroot(zz,nn)
Half:
-- Is a number half integer?
procedure
arg xx
-- Formula
return (Frac(Abs(xx))=0.5)
Hmean:
-- Harmonic mean
-- HM
procedure
nn = Arg()
if nn = 0 then say argument
-- Cf definition
numeric digits Digits()+1
zz = 0
do n = 1 to nn
xx = Arg(n)
if \ Datatype(xx,'n') then say argument n
if xx = 0 then say argument n
zz = zz+1/xx
end
if zz = 0 then say argument
return nn/zz
Hypot:
-- Hypothenusa
procedure
arg xx,yy
if \ Datatype(xx,'n') then say argument
if \ Datatype(yy,'n') then say argument
-- Formula
numeric digits Digits()+1
return Sqrt(xx*xx+yy*yy)
Integer:
-- Is a number integer?
procedure
arg xx
-- Formula
return Datatype(xx,'w')
Isqrt:
-- Integer square root
procedure
arg xx
if \ Datatype(xx,'n') then say argument
if xx < 0 then say argument
-- Fast
if xx < 1 then
return 0
if xx < 4 then
return 1
if xx < 9 then
return 2
-- Loop 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
Lambda:
-- Dirichlet lambda
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Formula
numeric digits Digits()+1
return (1-Power(2,-xx))*Zeta(xx)
Lambertw0:
-- Lambert W0
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Fast
if xx = 0 then
return 0
-- First guess
dd = Digits()+1
numeric digits 2
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
-- Dynamic precision
do n = 1 while dd > 3
d.n = dd; dd = Trunc(0.50*dd)
end
d.n = 3
-- Halley
do i = n to 1 by -1
numeric digits d.i
a = Exp(zz); b = a*zz; zz = zz-(b-xx)/(a+b-((zz+2)*(b-xx))/(2*zz+2))
end
return zz
Lambertwm1:
-- Lambert W-1
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx < -1/E() then say argument
if xx >= 0 then say argument
-- First guess
dd = Digits()+1
numeric 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
-- Dynamic precision
do n = 1 while dd > 3
d.n = dd; dd = Trunc(0.50*dd)
end
d.n = 3
-- Halley
do i = n to 1 by -1
numeric digits d.i
a = Exp(zz); b = a*zz; zz = zz-(b-xx)/(a+b-((zz+2)*(b-xx))/(2*zz+2))
end
return zz
Lcm:
-- Least common multiple function
procedure
arg xx,yy
if \ Datatype(xx,'n') then say argument
if \ Datatype(yy,'n') then say argument
xx = Abs(xx); yy = Abs(yy)
-- Fast
if yy = 0 then
return 0
-- Euclidian division
a = xx*yy
do until yy = 0
zz = xx//yy; xx = yy; yy = zz
end
return a%xx
Ln:
-- Natural logarithm base e
-- Log
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx <= 0 then say argument
-- Fast
if xx = 1 then
return 0
if xx = 2 then
return Ln2()
if xx = 4 then
return Ln4()
if xx = 10 then
return Ln10()
dd = Digits()
if glob.ln.xx.dd <> '' then
return glob.ln.xx.dd
-- Reduce argument to 0.5...1.5
numeric digits dd+2
do i = 0 by -1 while xx < 0.5
xx = xx+xx
end
do i = i while xx > 1.5
xx = xx*0.5
end
-- Taylor
q = (xx-1)/(xx+1); f = q; zz = q; v = q; q = q*q
do n = 3 by 2 until zz = v
v = zz
f = f*q; zz = zz+f/n
end
-- Undo reduce
zz = 2*zz+i*Ln2(); glob.ln.xx.dd = zz
return zz
Lngamma:
-- Logarithmic gamma
procedure expose glob.
arg xx
-- Formula
return Ln(Gamma(xx))
Log:
-- Natural logarithm base e
-- Ln
procedure expose glob.
arg xx
-- Alias
return Ln(xx)
Log10:
-- Common logarithm base 10
procedure expose glob.
arg xx
-- Formula
numeric digits Digits()+1
return Ln(xx)/Ln(10)
Logxy:
-- Logarithm x base y
procedure expose glob.
arg xx,yy
if yy = 1 then say argument
-- Formula
numeric digits Digits()+1
return Ln(xx)/Ln(yy)
Mant:
-- Mantissa
procedure
arg xx
if \ Datatype(xx,'n') then say argument
-- Fast
if xx = 0 then
return 0
-- Formula
zz = xx*1E+99999999
return Left(zz,Pos('E',zz)-1)
Natural:
-- Are all arguments in N?
procedure
do i = 1 to Arg()
if \ Datatype(Arg(i),'w') then say argument
if Arg(i) < 1 then say argument
end
return 1
Nroot:
-- Nth root
-- x^(1/n)
procedure expose glob.
arg xx,yy
if \ Datatype(xx,'n') then say argument
if \ Datatype(yy,'w') then say argument
if yy < 1 then say argument
if xx < 0 & Even(yy) then say argument
-- Fast
if xx = 0 then
return 0
if xx = 1 then
return 1
if yy = 2 then
return Sqrt(xx)
if yy = 3 then
return Cbrt(xx)
-- Sign
sx = Sign(xx); xx = Abs(xx)
-- First guess 3 digits accurate
d1 = Digits()
numeric digits 3
zz = Exp(Ln(xx)/yy)/1
-- Dynamic precision
d2 = d1+2
numeric digits d2
d = d2
do k = 1 while d > 5
d.k = d; d = Trunc(0.60*d)
end
d.k = 5
-- Newton
yi = 1/yy; y1 = yy-1
do i = k to 1 by -1
numeric digits d.i
zz = zz - yi*(zz-xx/zz**y1)
end
return sx*zz
Odd:
-- Is a number odd?
procedure
arg xx
-- Formula
if Integer(xx) then
return Abs(xx//2)
else
return 0
Perm:
-- Permutations
procedure
arg xx,yy
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
if \ Datatype(yy,'w') 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
Power:
-- Real power
-- x^y
procedure expose glob.
arg xx,yy
if \ Datatype(xx,'n') then say argument
if \ Datatype(yy,'n') then say argument
if xx < 0 & \ Integer(yy) then say argument
-- Fast
numeric digits Digits()+1
if xx = 0 then
return 0
if xx = 1 then
return 1
if yy = -1 then
return 1/xx
if yy = 0 then
return 1
if yy = 1 then
return xx
-- Formula
if Integer(yy) then
return xx**yy
if yy = 0.5 then
return Sqrt(xx)
if Half(yy) then
return Sqrt(xx)**Sign(yy)*xx**(yy%1)
else
return Exp(yy*Ln(xx))
Powmod:
-- Power modulus
procedure
arg xx,yy,zz
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
if \ Datatype(yy,'w') then say argument
if yy < 0 then say argument
if \ Datatype(zz,'w') then say argument
if zz < 1 then say argument
-- Fast
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
Primecount:
-- Prime count
-- Pi(x) estimated number of primes below x
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
if xx = 1 then
return 0
-- Formula
return Round(xx/(Ln(xx)-1),0)
Primeest:
-- Nth prime number estimate
procedure expose glob.
arg xx
if \ Datatype(xx,'w') 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# product of primes
procedure expose prim. glob.
arg xx
if \ Datatype(xx,'w') then say argument
-- Fast
if xx = 0 then
return 1
if Abs(xx) = 1 then
return 2
-- Get primes
if xx < 0 then do
call Primes(xx); p = -xx
end
else
p = Primes(xx)
-- Calculate product
numeric digits Digits()+2
zz = 1
do n = 1 to p
zz = zz*prim.n
end
return zz
Qmean:
-- Quadratic mean
-- QM, rms
procedure
nn = Arg()
if nn = 0 then say argument
-- Cf definition
numeric digits Digits()+1
zz = 0
do n = 1 to nn
xx = Arg(n)
if \ Datatype(xx,'n') then say argument n
zz = zz+xx*xx
end
return Sqrt(zz/nn)
Qtrt:
-- Quartic root
-- x^(1/4)
procedure
arg xx
if \ Datatype(xx,'n') then say argument
if xx < 0 then say argument
-- Fast
if xx = 0 then
return 0
if xx = 1 then
return 1
-- Reduce argument to 1...10000
e = Xpon(xx); e = (e-(3*(e<0)))%4; f = -4*e; xx = Std(xx)'E'f
-- First guess 2 digits accurate
dd = Digits()+2
numeric digits 2
select
when xx < 16 then
zz = 1+(xx-1)/15
when xx < 81 then
zz = 2+(xx-16)/65
when xx < 256 then
zz = 3+(xx-81)/175
when xx < 625 then
zz = 4+(xx-256)/360
when xx < 1296 then
zz = 5+(xx-625)/671
when xx < 2401 then
zz = 6+(xx-1296)/1105
when xx < 4096 then
zz = 7+(xx-2401)/1695
when xx < 6561 then
zz = 8+(xx-4096)/2465
otherwise
zz = 9+(xx-6561)/3439
end
-- Dynamic precision
do n = 1 while dd > 4
d.n = dd; dd = Trunc(0.48*dd)
end
d.n = 4
-- Halley
do i = n to 1 by -1
numeric digits d.i
z4 = zz*zz*zz*zz; z5 = z4*zz; zz = zz-(2*z5-2*zz*xx)/(3*xx+5*z4)
end
-- Undo reduce
return zz'E'e
Rad:
-- Degrees -> Radians
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Formula
numeric digits Digits()+1
return xx*Pi()/180
Radical:
-- Radical
-- Product of unique factors
procedure expose ufac.
arg xx
-- 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 yy = '' then do
yy = xx; xx = 1
end
if \ Datatype(xx,'w') then say argument
if \ Datatype(yy,'w') then say argument
if xx >= yy then say argument
end
-- Get and save first seed from system Date and Time
numeric digits 30
if glob.rand = '' then do
d = Date('s')
a = Substr(d,3,2); b = Substr(d,5,2); c = Substr(d,7,2)
t = Time('l')
d = Substr(t,1,2); e = Substr(t,4,2); f = Substr(t,7,2)
g = Substr(t,10,1); h = Substr(t,11,1); i = Substr(t,12,1)
glob.rand = h||f||d||b||a||c||e||g||i
end
-- Calculate next random number cf HP calculators
glob.rand = Right((glob.rand*2851130928467),15)
-- Uniform deviate (0,1)
zz = '0.'Left(glob.rand,12)
-- or specified range (x,y)
if xx <> '' then
zz = Floor(zz*(yy+1-xx)+xx)
numeric digits 12
return zz+0
Real:
-- Are all arguments in R?
procedure
do i = 1 to Arg()
if \ Datatype(Arg(i),'n') then say argument
end
return 1
Repunit:
-- Repeated 1's
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Formula
return Copies('1',xx)
Rfact:
-- Rising factorial
procedure expose glob.
arg xx,yy
if \ Datatype(xx,'w') then say argument
if xx = 0 then say argument
if \ Datatype(yy,'w') then say argument
if yy < 0 then say argument
-- Fast
if xx = 1 then
return 1
if yy = 0 then
return 1
if glob.Rfact.xx.yy <> '' then
return glob.Rfact.xx.yy
-- 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 = 0
if \ Datatype(xx,'n') then say argument
if \ Datatype(yy,'w') then say argument
-- Formula
if yy < 0 then do
yy = Abs(yy); a = 1'E'yy
return Format(xx/a,,0,0)*a
end
else
return Format(xx,,yy,0)
Sci:
-- Convert to scientific format
procedure
arg xx
if \ Datatype(xx,'n') then say argument
-- Formula
return Mant(xx)'E'Xpon(xx)
Sec:
-- Secant
procedure expose glob.
arg xx
if xx = 0 then
return 1
-- Formula
numeric digits Digits()+1
zz = Cos(xx)
if zz = 0 then say argument
return 1/zz
Sech:
-- Secant hyperbolic
procedure expose glob.
arg xx
-- Formula
numeric digits Digits()+1
return 1/Cosh(xx)
Sigma:
-- Sigma
-- Sum of divisors
procedure expose divi.
arg xx
-- Formula
return Divisor(xx,1)
Sin:
-- Sine
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Fast
if xx = 0 then
return 0
-- Reflect
if xx < 0 then
return -Sin(-xx)
-- Reduce argument to 0...2pi
numeric digits Digits()+Max(Xpon(xx),0)+1
xx = xx//tau()
-- Reduce argument to 0...pi/2
select
when xx < Halfpi() then
s = 1
when xx < Pi() then do
s = 1; xx = Pi()-xx
end
when xx < Pi()+Halfpi() then do
s = -1; xx = xx-Pi()
end
otherwise do
s = -1; xx = tau()-xx
end
end
-- Taylor
t = xx; zz = xx; xx = xx*xx
do n = 2 by 2 until zz = v
v = zz
t = -t*xx/(n*(n+1)); zz = zz+t
end
return s*zz
Sinh:
-- Sine hyperbolic
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Reflect
if xx < 0 then
return -Sinh(-xx)
-- Fast
if xx = 0 then
return 0
-- Taylor
numeric digits Digits()+1
if \ Integer(xx) & xx < 5 then do
t = xx; zz = xx; xx = xx*xx
do n = 3 by 2 until zz = v
v = zz
t = (t*xx)/(n*n-n); zz = zz+t
end
return zz
end
-- Formula
zz = Exp(xx)
return (zz*zz-1)/(2*zz)
Sqrt:
-- Square root
-- x^(1/2)
procedure
arg xx
if \ Datatype(xx,'n') then say argument
if xx < 0 then say argument
-- Fast
if xx = 0 then
return 0
if xx = 1 then
return 1
dd = Digits()+2
numeric digits dd
if xx = 2 then
return Sqrt2()
if xx = 3 then
return Sqrt3()
if xx = 5 then
return Sqrt5()
-- Reduce argument to 1...100
e = Xpon(xx); e = (e-(e<0))%2; f = -2*e; xx = Std(xx)'E'f
-- First guess 2 digits accurate
numeric digits 2
select
when xx < 4 then
zz = 1+(xx-1)/3
when xx < 9 then
zz = 2+(xx-4)/5
when xx < 16 then
zz = 3+(xx-9)/7
when xx < 25 then
zz = 4+(xx-16)/9
when xx < 36 then
zz = 5+(xx-25)/11
when xx < 49 then
zz = 6+(xx-36)/13
when xx < 64 then
zz = 7+(xx-49)/15
when xx < 81 then
zz = 8+(xx-64)/17
otherwise
zz = 9+(xx-81)/19
end
-- Dynamic precision
do n = 1 while dd > 4
d.n = dd; dd = Trunc(0.36*dd)
end
d.n = 4
-- Halley
do i = n to 1 by -1
numeric digits d.i
z2 = zz*zz; zz = zz-2*zz*(z2-xx)/(3*z2+xx)
end
-- Undo reduce
return zz'E'e
Std:
-- Convert to standard format
procedure
arg xx
if \ Datatype(xx,'n') then say argument
-- Formula
return Format(xx,,,0)
Tan:
-- Tangent
procedure expose glob.
arg xx
-- Fast
if xx = 0 then
return 0
-- Formula
numeric digits Digits()+1
zz = Cos(xx)
if zz = 0 then say argument
return Sin(xx)/zz
Tanh:
-- Tangent hyperbolic
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
-- Fast
if xx = 0 then
return 0
-- Reflect
if xx < 0 then
return -Tanh(-xx)
-- Formula
numeric digits Digits()+2
if xx < 1 then
numeric digits Digits()-Xpon(xx)
zz = Exp(2*xx)
return (zz-1)/(zz+1)
Totient:
-- Euler's totient function
-- Phi(x) number of relative primes to x
procedure expose fact.
arg xx
if \ Datatype(xx,'n') then say argument
if xx < 1 then say argument
-- Fast
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
-- Derivative of Digamma
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx <= 0 & Integer(xx) then say argument
-- Fast sum
numeric digits Digits()+2
if xx > 0 & xx < 50 then do
if Integer(xx) then do
s = 0
do i = 1 to xx-1
s = s+1/(i*i)
end
return Pi()*Pi()/6-s
end
if Half(xx) then do
s = 0
do i = 1 to xx
a = 2*i-1
s = s+1/(a*a)
end
return Halfpi()*Pi()-4*s
end
end
-- Reduce argument towards a higher value
d = Digits(); a = 0
do while xx < d
a = a+1/(xx*xx); xx = xx+1
end
-- Series
zz = 0; v = 0
do n = 2 by 2
zz = zz+Bernoulli(n)/xx**(n+1)
if zz = v then
leave
v = zz
end
-- Undo reduce
return zz+1/xx+1/(2*xx*xx)+a
Whole:
-- Are all arguments in Z?
procedure
do i = 1 to Arg()
if \ Datatype(Arg(i),'w') then say argument
end
return 1
Xpon:
-- Exponent
procedure
arg xx
if \ Datatype(xx,'n') then say argument
-- Formula
numeric digits 9
if xx = 0 then
return 0
else
return Right(xx*1E+99999999,9)-99999999
Zero:
-- Are all arguments <> 0?
procedure
do i = 1 to Arg()
if Arg(i) = 0 then say argument
end
return
Zeta:
-- Zeta
procedure expose glob.
arg xx
if \ Datatype(xx,'n') then say argument
if xx = 1 then say argument
-- Fast
dd = Digits()
numeric digits dd+3
if xx = 0 then
return -0.5
if xx = 3 then
return Apery()
if xx < 0 & Even(xx) then
return 0
-- Formula
if xx < 0 & Odd(xx) then
return ((-1)**-xx*Bernoulli(1-xx))/(1-xx)
if xx > 0 & Even(xx) then
return ((-1)**(xx/2+1)*Bernoulli(xx)*(Tau())**xx)/(2*Fact(xx))
-- Reflection
if xx < 0 then
return -2*Factorial(-xx)*Sin(Pi()*-xx/2)*Zeta(1-xx)/Power(Tau(),1-xx)
-- Selected odd integers cf Plouffe
if xx > 4 & xx < 22 & Odd(xx) then do
select
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(Tau()*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
return zz
end
-- Standard for all other xx
-- Max iterations estimate
select
when dd < 15 then
n = dd*2
when dd < 89 then
n = dd*3
otherwise
n = dd*4
end
-- Reduce argument by factor
a = (-1)/(2**n*(1-Power(2,1-xx)))
-- Series
s = 0; zz = 0
do j = 0 to 2*n-1
b = (-1)**j; c = Power(j+1,xx)
if j < n then
s = 0
else
s = s+Comb(n,j-n)
zz = zz+(s-2**n)*b/c
end
-- Undo reduce
return a*zz
-- Module Helper.inc - 11 Apr 2025
-- Supporting procedures
Sort:
-- Sort 1 or more key stems, syncing 0 or more data stems
arg keys!,data!
kn! = Words(keys!)
do x! = 1 to kn!
key!.x! = Word(keys!,x!)
end
dn! = Words(data!)
do x! = 1 to dn!
data!.x! = Word(data!,x!)
end
n! = Value(key!.1||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!
-- Insertion sort
if r!-l! < 20 then do
do i! = l!+1 to r!
do x! = 1 to kn!
k!.x! = Value(key!.x!||i!)
end
do x! = 1 to dn!
d!.x! = Value(data!.x!||i!)
end
do j!=i!-1 to l! by -1
do x! = 1 to kn!
a! = Value(key!.x!||j!)
if a! > k!.x! then
leave x!
if a! = k!.x! then
if x! < kn! then
iterate x!
leave j!
end
k! = j!+1
do x! = 1 to kn!
t! = Value(key!.x!||j!)
call Value key!.x!||k!,t!
end
do x! = 1 to dn!
t! = Value(data!.x!||j!)
call Value data!.x!||k!,t!
end
end
k! = j!+1
do x! = 1 to kn!
call Value key!.x!||k!,k!.x!
end
do x! = 1 to dn!
call Value data!.x!||k!,d!.x!
end
end
if s! = 0 then
leave
l! = sl!.s!; r! = sr!.s!; s! = s!-1
end
-- Quicksort
else do
m! = (l!+r!)%2
do x! = 1 to kn!
a! = Value(key!.x!||l!); b! = Value(key!.x!||m!)
if a! > b! then do
do y! = 1 to kn!
t! = Value(key!.y!||l!); u! = Value(key!.y!||m!)
call Value key!.y!||l!,u!; call Value key!.y!||m!,t!
end
do y! = 1 to dn!
t! = Value(data!.y!||l!); u! = Value(data!.y!||m!)
call Value data!.y!||l!,u!; call Value data!.y!||m!,t!
end
leave
end
if a! < b! then
leave
end
do x! = 1 to kn!
a! = Value(key!.x!||l!); b! = Value(key!.x!||r!)
if a! > b! then do
do y! = 1 to kn!
t! = Value(key!.y!||l!); u! = Value(key!.y!||r!)
call Value key!.y!||l!,u!; call Value key!.y!||r!,t!
end
do y! = 1 to dn!
t! = Value(data!.y!||l!); u! = Value(data!.y!||r!)
call Value data!.y!||l!,u!; call Value data!.y!||r!,t!
end
leave
end
if a! < b! then
leave
end
do x! = 1 to kn!
a! = Value(key!.x!||m!); b! = Value(key!.x!||r!)
if a! > b! then do
do y! = 1 to kn!
t! = Value(key!.y!||m!); u! = Value(key!.y!||r!)
call Value key!.y!||m!,u!; call Value key!.y!||r!,t!
end
do y! = 1 to dn!
t! = Value(data!.y!||m!); u! = Value(data!.y!||r!)
call Value data!.y!||m!,u!; call Value data!.y!||r!,t!
end
leave
end
if a! < b! then
leave
end
i! = l!; j! = r!
do x! = 1 to kn!
p!.x! = Value(key!.x!||m!)
end
do until i! > j!
do i! = i!
do x! = 1 to kn!
a! = Value(key!.x!||i!)
if a! < p!.x! then
leave x!
if a! = p!.x! then
if x! < kn! then
iterate x!
leave i!
end
end
do j! = j! by -1
do x! = 1 to kn!
a! = Value(key!.x!||j!)
if a! > p!.x! then
leave x!
if a! = p!.x! then
if x! < kn! then
iterate x!
leave j!
end
end
if i! <= j! then do
do x! = 1 to kn!
t! = Value(key!.x!||i!); u! = Value(key!.x!||j!)
call Value key!.x!||i!,u!; call Value key!.x!||j!,t!
end
do x! = 1 to dn!
t! = Value(data!.x!||i!); u! = Value(data!.x!||j!)
call Value data!.x!||i!,u!; call Value data!.x!||j!,t!
end
i! = i!+1; j! = j!-1
end
end
if j!-l! < r!-i! then do
if i! < r! then do
s! = s!+1; sl!.s! = i!; sr!.s! = r!
end
r! = j!
end
else do
if l! < j! then do
s! = s!+1; sl!.s! = l!; sr!.s! = j!
end
l! = i!
end
end
end
end
return
-- Module Numbers.inc - 11 Apr 2025
-- Useful numbers and functions in number theory
Abundant:
-- Is a number abundant?
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
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 number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
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 \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
if \ Datatype(yy,'w') then say argument
if yy < 1 then say argument
-- Cf definition
if yy = 1 then
return Prime(xx)
if yy = 2 then
return Semiprime(xx)
if Factors(xx) = yy then
return 1
else
return 0
Arithmetic:
-- Is a number arithmetic?
procedure expose divi.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
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 Integer(s/divi.0) then
return 1
else
return 0
Bell:
-- Bell number
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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
return zz
Beraha:
-- Beraha number
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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
-- Formula
numeric digits Digits()+1
if xx = 8 then
return 2+Sqrt(2)
if xx = 10 then
return 0.5*(5+Sqrt(5))
return 2+2*Cos(Tau()/xx)
Bernoulli:
-- Bernoulli number
procedure expose glob. work.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
if xx = 0 then
return 1
if xx = 1 then
return -0.5
if xx//2 = 1 then
return 0
p = Digits()
if glob.bernoulli.xx.p <> '' then
return glob.bernoulli.xx.p
-- Recurring method Akiyama-Tanigawa
numeric digits Max(p,xx+xx)
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
-- Result
zz = work.0
glob.bernoulli.xx.p = zz
return zz
Cake:
-- Cake number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Formula
return (xx*xx*xx+5*xx+6)/6
Catalann:
-- Catalan number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Recurring
numeric digits Digits()+Xpon(xx)
zz = 1
do n = 1 to xx
zz = zz*(4*n-2)/(n+1)
end
return zz
Caterer:
-- Lazy caterer's number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Formula
return 0.5*(xx*xx+xx+2)
Central:
-- Central binomial coefficient number
procedure expose glob.
arg xx
-- Formula
return Comb(2*xx,xx)
Chowla:
-- Chowla number
procedure
arg xx
-- Formula
return Aliquot(xx)-1
Composite:
-- Is a number composite?
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
if xx = 1 then
return 0
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
-- 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
Conwayn:
-- Conway look-and-say number
procedure
arg xx
if \ Datatype(xx,'w') 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
-- Formula
return (Gcd(xx,yy) = 1)
Cullen:
-- Cullen number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Formula
return xx*2**xx+1
Deficient:
-- Is a number deficient?
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
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 number
procedure
arg xx
if \ Datatype(xx,'w') 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
return zz
Favard:
-- Favard number
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
if xx = 0 then
return 1
-- Formula
numeric digits Digits()+1
if xx = 1 then
return Halfpi()
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
-- Recurring
numeric digits Digits()+1
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
return zz.xx
Fermat:
-- Fermat number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Formula
numeric digits Digits()+1
zz = 2**(2**xx)
return zz
Ffactor:
-- First prime factor by trial division
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 2 then say argument
-- Fast
if Even(xx) then
return 2
if Right(xx,1) = 5 then
return 5
if Prime(xx) 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
if xx > 1 then
return xx
return 0
Fibonacci:
-- Fibonacci number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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
return zz
Goldbach:
-- Goldbach number
procedure expose prim. flag.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 4 then say argument
-- Scan primes
p = Primes(xx); zz = 0
do i = 2 to xx%2
if flag.i then do
j = xx-i
if flag.j then do
zz = zz+1
end
end
end
return zz
Golombn:
-- Golomb-Silverman number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
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
return zz.xx
Gould:
-- Gould number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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
return zz.xx
Gregory1:
-- Gregory number 1
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
if xx = 1 then
return 0.5
-- Recurring
numeric digits Digits()+2
zz.1 = 0.5
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
return (-1)**(xx-1)*zz.xx
Gregory2:
-- Gregory number 2
procedure
arg xx
if \ Datatype(xx,'n') then say argument
if xx < 1 then say argument
-- Fast
if xx = 1 then
return 0.25*Pi()
-- Formula
return Arctan(1/xx)
Harmonic:
-- Harmonic number
procedure
arg xx,yy
if yy = '' then
yy = 1
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
if \ Datatype(yy,'w') then say argument
if yy < 0 then say argument
-- Fast
if xx = 0 then
return 0
if xx < 2 then
return 1
-- From definition
numeric digits Digits()+2
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
return zz
Highcomposite:
-- Is a number highly composite?
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- ... to do
return 0
Home:
-- Home prime number
procedure expose fact. glob. work.
arg xx
if \ Datatype(xx,'w') 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.i
end
end
return xx
Jacobsthal:
-- Jacobsthal number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
if xx < 3 then
return 1
-- Formula
numeric digits Digits()+2
zz = (2**xx-(-1)**xx)/3
return zz
Kaprekar:
-- Is a number Kaprekar?
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
if xx < 101 then do
k = '1 9 45 55 99'
if Wordpos(xx,k) = 0 then
return 0
else
return 1
end
-- 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 number
procedure expose glob.
arg xx,yy
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
if \ Datatype(yy,'w') then say argument
if yy < 1 then say argument
if xx < yy then say argument
-- Fast
if xx = yy then
return 1
-- Formula
s = (-1)**xx
if yy = 1 then
return s*Fact(xx)
else
return s*Comb(xx-1,yy-1)*Fact(xx)/Fact(yy)
Lambdan:
-- Lambda number
procedure expose efac.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
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
Lebesguen:
-- Lebesgue number
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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(Tau()/9)-5*Sin(Pi()/9)-Cos(Pi()/18))/Pi()
-- Series expansion
numeric digits Digits()+2
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()
return zz
Leonardo:
-- Leonardo number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
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
Lucas:
-- Lucas number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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
return zz
Magic:
-- Magic number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Formula
return 0.5*(xx*xx*xx+xx)/1
Metallic:
-- Metallic ratio number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
if xx = 0 then
return 1
-- Formula
if xx = 1 then
return Golden()
if xx = 2 then
return Silver()
if xx = 3 then
return Bronze()
return 0.5*(xx+Sqrt(xx*xx+4))
Moebius:
-- Moebius number
procedure expose glob. fact. ufac.
arg xx
-- 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 number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
if xx < 3 then
return 1
-- Recurring
numeric digits Digits()+2
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
return zz
Narayana:
-- Narayana cows number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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
return zz
Nextprime:
-- Next prime number
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 2 then say argument
-- Find next prime
xx = xx+1+odd(xx)
do zz = xx by 2 until prime(zz)
end
return zz
Padovan:
-- Padovan number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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+b
a = b; b = c; c = zz
end
return zz
Partition:
-- Partition number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
if xx = 0 then
return 1
-- Recurring
numeric digits Digits()+2
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-0.5*k*(3*k+1)
s = s+(-1)**(k+1)*(yy.a+yy.b)
end
yy.n = s
end
return yy.xx
Pell1:
-- Pell number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
if xx < 2 then
return xx
-- Recurring
numeric digits Digits()+2
a = 0; b = 1; zz = 0
do n = 2 to xx
zz = a+2*b
a = b; b = zz
end
return zz
Pell2:
-- Pell-Lucas companion number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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
return zz
Perfect:
-- Is a number perfect?
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
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 number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
if xx = 0 then
return 3
if xx = 1 then
return 0
if xx = 2 then
return 2
-- Recurring
numeric digits Digits()+2
a = 3; b = 0; c = 2; zz = 0
do n = 3 to xx
zz = a+b
a = b; b = c; c = zz
end
return zz
Persistence:
-- Additive persistence
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
if xx = 0 then
return 0
-- Cf definition
do zz = 1 until xx < 10
xx = Digitsum(xx)
end
return zz
Pisanoprime:
-- Pisano period
procedure
arg xx,yy
if \ Datatype(xx,'w') then say argument
if \ prime(xx) then say argument
if \ Datatype(yy,'w') then say argument
if yy < 1 then say argument
-- Pisano period
zz = 0
return zz
Pollardrho:
-- Find a prime factor by Pollard-Rho
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 2 then say argument
-- Fast
-- Fast
pr = '2 3 5 7 11 13 17 19 23 29'
do i = 1 to Words(pr)
p = Word(pr,i)
if xx//p = 0 then
return p
end
if Prime(xx) then
return xx
-- Square?
s = Isqrt(xx)
if s*s = xx then
return Pollardrho(s)
-- Pollard Rho
a = Random(1,9); b = a; c = Random(1,9); zz = 1; n = 0
-- a = 2; b = a; c = 1; zz = 1; n = 0
m = Sqrt(xx)
do while zz = 1 & n < m
a = (a*a+c)//xx; b = (b*b+c)//xx; b = (b*b+c)//xx
zz = Gcd(a-b,xx)
if zz = xx then
return 0
n = n+1
end
if Prime(zz) then
return zz
else
return Pollardrho(zz)
Practical:
-- Is a number practical?
procedure expose fact.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
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.i > s+1
then return 0
f = f*fact.i; s = Sigma(f)
end
return 1
Prevprime:
-- Previous prime number
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 3 then say argument
-- Fast
if xx = 3 then
return 2
-- Find previous prime
xx = xx-1-odd(xx)
do zz = xx by -2 until prime(zz)
end
return zz
Prime:
-- Is a number prime?
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
if xx < 2 then
return 0
xx = xx+0; lp = '2 3 5 7 11 13 17 19 23 29 31 37 41'
if xx < 42 then do
if Wordpos(xx,lp) = 0 then
return 0
else
return 1
end
if Right(xx,1) = 0 then
return 0
if Right(xx,1) = 5 then
return 0
if xx//2 = 0 then
return 0
if xx//3 = 0 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
Primell:
-- Is a Mersenne number prime?
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
if \ Prime(xx) then say argument
-- Fast
if xx = 2 then
return 1
-- Lucas-Lehmer
m = 2**xx-1; a = 4
do xx-2
a = (a*a-2)//m
end
if a//m = 0 then
return 1
else
return 0
Pronic:
-- Pronic number
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Formula
numeric digits Digits()+2
zz = xx*xx+xx
return zz
Recaman:
-- Recaman number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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. glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
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 '
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 number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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
Squarefree:
-- Is a number square free?
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
if xx < 4 then
return 1
-- Recurring
o = Odd(xx)
do k = 2+o by 1+o to Isqrt(xx)
if xx//(k*k) = 0 then
return 0
end
return 1
Squfof:
-- Find a prime factor by square form factorization
procedure expose mult. glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 2 then say argument
-- Fast
pr = '2 3 5 7 11 13 17 19 23 29'
do i = 1 to Words(pr)
p = Word(pr,i)
if xx//p = 0 then
return p
end
if Prime(xx) then
return xx
-- Square?
s = Isqrt(xx)
if s*s = xx then
return Squfof(s)
-- Multipliers
m = '1 3 5 7 11 15 21 33 35 55 77 105 165 231 385 1155'
do i = 1 to Words(m)
mult.i = Word(m,i)
end
mult.0 = i-1
-- Heuristic classic method
bb = Isqrt(s+s)*6
do m = 1 for mult.0
k = mult.m
d = xx*k; po = Isqrt(d); qq = d-po*po
if qq = 0 then
iterate m
p = po; pp = po; qp = 1
do i = 2 while i < bb
b = (po+p)%qq; p = b*qq-p; q = qq; qq = qp+b*(pp-p); r = Isqrt(qq)
if i//2 = 0 then
if r*r = qq then
leave
qp = q; pp = p
end
if i >= bb then
iterate
b = (po-p)%r; p = b*r+p; pp = p; qp = r; qq = (d-pp*pp)%qp
do until p = pp
pp = p; b = (po+p)%qq; q = qq; p = b*qq-p; qq = qp+b*(pp-p); qp = q
end
r = Gcd(xx,qp)
if r <> 1 then
if r <> xx then
if Prime(r) then
return r
end
return 0
Stirling1:
-- Stirling number 1
procedure expose glob.
arg xx,yy
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
if \ Datatype(yy,'w') then say argument
if yy < 0 then say argument
-- Fast
if yy = xx then
return 1
if yy > xx then
return 0
if yy = 0 then
return 0
-- Formula
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(0.5*Fact(xx-1)*(Harmonic(xx-1)**2-Harmonic(xx-1,2)))
if yy = xx-3 then
return s*Comb(xx,2)*Comb(xx,4)
if yy = xx-2 then
return s*Round(0.25*(3*xx-1)*Comb(xx,3))
if yy = xx-1 then
return s*Comb(xx,2)
-- Definition
numeric digits Digits()+2
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
return s*zz.yy
Stirling2:
-- Stirling number 2
procedure expose glob.
arg xx,yy
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
if \ Datatype(yy,'w') then say argument
if yy < 0 then say argument
if xx < yy then say argument
-- Fast
if xx = 0 then
return 0
if yy = 0 then
return 0
if xx = yy then
return 1
if yy = 1 then
return 1
-- Formula
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)
-- Definition
numeric digits Digits()+2
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
return zz.zz
Sylvester:
-- Sylvester number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
if xx > 33 then say argument
-- Definition
numeric digits Digits()+2
zz = 2
do n = 2 to xx
zz = zz*zz-zz+1
end
return zz
Taun:
-- Ramanujan Tau number
procedure expose divi.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Niebur series
numeric digits Digits()+4
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
return xx**4*Sigma(xx)-24*s
Tetranaccin:
-- Tetranacci number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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
Thue:
-- Thue-Morse number
procedure
arg xx
if \ Datatype(xx,'w') 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
Tribonaccin:
-- Tribonacci number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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
Ulam:
-- Ulam number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
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
return zz
Wedderburn:
-- Wedderburn number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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 = 0.5*zz.a*(zz.a+1)
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
return zz.xx
Woodall:
-- Woodall number
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Formula
numeric digits Digits()+2
zz = xx*2**xx-1
return zz
ZigZag:
-- Zigzag alternating permutations number
procedure expose glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
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 = 0.5*s
end
zz = zz.xx
return zz
-- Module Polynomial.inc - 22 Mar 2025
-- Polynomial arithmetic, functions and tools
-- Coefficients are coded as string, highest order first
-- Examples 'a 0 c 0' = ax^3+cx, '1 0 0' = x^2, '2' = 2
Padd:
-- Addition
-- p1+p2
procedure
arg xx,yy
if xx = '' then say argument
if yy = '' then say argument
-- Add
wx = Words(xx); wy = Words(yy); wm = Max(wx,wy)
if wx < wy then
xx = Copies('0 ',wm-wx) xx
else
yy = Copies('0 ',wm-wy) yy
zz = ''
do i = 1 to wm
wx = Word(xx,i); wy = Word(yy,i)
if \ Datatype(wx,'n') then say argument i
if \ Datatype(wy,'n') then say argument i
zz = zz wx+wy
end
return zz
Parr2lst:
-- Array -> List
procedure expose poly.
-- Compose list
zz = ''
do i = 1 to poly.0
zz = zz poly.coef.i
end
return zz
Pcube:
-- Cube
-- p^3
procedure
arg xx
-- Formula
return Ppow(xx,3)
Pdif:
-- Differentiation
-- p'
procedure
arg xx
if xx = '' then say argument
-- Differentiate
wx = Words(xx); wm = wx-1
if wm = 0 then
return 0
zz = ''
do i = 1 to wm
w = Word(xx,i)
if \ Datatype(w,'n') then say argument i
zz = zz (wm-i+1)*w
end
return zz
Pdiv:
-- Long division
-- p1/p2
procedure
arg xx,yy
if xx = '' then say argument
if yy = '' then say argument
wx = Words(xx); wy = Words(yy)
do i = 1 to wx
if \ Datatype(Word(xx,i),'n') then say argument
end
do i = 1 to wy
if \ Datatype(Word(yy,i),'n') then say argument
end
-- Fast
if wx < wy then
return 0','xx
if wy = 1 then
return Pmul(1/yy,xx)','0
-- Divide
numeric digits Digits()+2
nx = xx; dx = yy Copies('0 ',wx-wy); qx = ''
do until Words(nx) < wy
q = Word(nx,1)/Word(dx,1); qx = qx q; z = ''
do i = 1 to Words(nx)
z = z Word(nx,i)-q*Word(dx,i)
end
nx = Subword(z,2); dx = Subword(dx,1,Words(dx)-1)
end
return qx','nx
Peval:
-- Evaluation
-- Value of p1 for y
procedure
arg xx,yy
if xx = '' then say argument
if yy = '' then say argument
if \ Datatype(yy,'n') then say argument
-- Evaluate
numeric digits Digits()+2
zz = 0
do i = 1 to Words(xx)
w = Word(xx,i)
if \ Datatype(w,'n') then say argument i
zz = zz*yy+w
end
return zz
Plst2form:
-- List -> Formula
procedure
arg xx
-- Fast
if xx = '' then
return 0
-- Compose formula
zz = ''; wm = Words(xx)
do i = 1 to wm
w = Word(xx,i)
if \ Datatype(w,'n') then say argument i
if w <> 0 then do
select
when w < 0 then
s = '-'
when i > 1 then
s = '+'
otherwise
s = ''
end
w = Abs(w); e = wm-i
if w = 1 & e > 0 then
w = ''
else
w = Std(w)
select
when e > 1 then
p = 'x^'e
when e = 1 then
p = 'x'
otherwise
p = ''
end
zz = zz||s||w||p
end
end
if zz = '' then
zz = 0
return zz
Pmul:
-- Multiplication
-- p1*p2
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
w = Word(xx,i)
if \ Datatype(w,'n') then say argument i
work.coefx.i = w
end
do i = 1 to wy
w = Word(yy,i)
if \ Datatype(w,'n') then say argument i
work.coefy.i = w
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.coefx.i*work.coefy.j
end
end
return Parr2lst()
Pneg:
-- Negation
-- -p
procedure
arg xx
if xx = '' then say argument
-- Negate
zz = ''
do i = 1 to Words(xx)
w = Word(xx,i)
if \ Datatype(w,'n') then say argument i
zz = zz (-w)
end
return Strip(zz)
Pnorm:
-- Normalization
procedure
arg xx
if xx = '' then say argument
-- Normalize
zz = ''
do i = 1 to Words(xx)
w = Word(xx,i)
if \ Datatype(w,'n') then say argument i
zz = zz w/1
end
return Strip(zz)
Ppow:
-- Integer power
-- p^n
procedure expose poly. comb. work.
arg xx,yy
if xx = '' then say argument
if \ Datatype(yy,'w') then say argument
if yy < 0 then say argument
-- Fast
poly. = 0
if yy = 0 then
return 1
-- Calculate power
numeric digits Digits()+2
wx = Words(xx); zz = wx*yy-yy+1
poly.0 = zz
select
when wx = 1 then do
-- Power of a real number
if \ Datatype(xx,'n') then say argument
poly.coef.1 = xx**yy
end
when wx = 2 then do
-- Newton's binomial
w1 = Word(xx,1); w2 = Word(xx,2)
if \ Datatype(w1,'n') then say argument
if \ Datatype(w2,'n') then say argument
call Combinations -yy
do i = 1 to zz
j = yy-i+1; k = i-1
poly.coef.i = comb.yy.k*w1**j*w2**k
end
end
otherwise do
-- Repeated multiplication
do i = 1 to wx
w = Word(xx,i)
if \ Datatype(w,'n') then say argument i
poly.coef1.i = w; poly.coef2.i = w
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.coef1.j*poly.coef2.k
end
end
if i = yy then
leave i
wx = wx+wy-1
do j = 1 to wx
poly.coef1.j = work.coef.j
end
end
do i = 1 to zz
poly.coef.i = work.coef.i
end
end
end
return Parr2lst()
Pquartic:
-- Quartic
-- p^4
procedure
arg xx
-- Formula
return Psquare(Psquare(xx))
Prev:
-- Coefficient reversion
procedure
arg xx
if xx = '' then say argument
-- Revert
zz = ''
do i = 1 to Words(xx)
zz = Word(xx,i) zz
end
return zz
Psci:
-- Scientific notation
procedure
arg xx
if xx = '' then say argument
-- Convert
zz = ''
do i = 1 to Words(xx)
w = Word(xx,i)
if \ Datatype(w,'n') then say argument i
zz = zz Sci(w)
end
return Strip(zz)
Psquare:
-- Square
-- p^2
procedure
arg xx
-- Formula
return Pmul(xx,xx)
Pstd:
-- Standard notation
procedure
arg xx
if xx = '' then say argument
-- Convert
zz = ''
do i = 1 to Words(xx)
w = Word(xx,i)
if \ Datatype(w,'n') then say argument i
zz = zz Std(w)
end
return Strip(zz)
Psub:
-- Subtraction
-- p1-p2
procedure
arg xx,yy
if xx = '' then say argument
if yy = '' then say argument
-- Subtract
wx = Words(xx); wy = Words(yy); wm = Max(wx,wy)
if wx < wy then
xx = Copies('0 ',wm-wx) xx
else
yy = Copies('0 ',wm-wy) yy
zz = ''
do i = 1 to wm
wx = Word(xx,i); wy = Word(yy,i)
if \ Datatype(wx,'n') then say argument i
if \ Datatype(wy,'n') then say argument i
zz = zz wx-wy
end
return zz
-- Module Rational.inc - 22 Mar 2025
-- Rational arithmetic, functions and tools
-- Fractions are coded as string 'numerator denominator'
-- Examples '7 3' = 7/3; '13' = '13 1' = 13; '1 7' = 1/7
Rabs:
-- Absolute value
-- |r|
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Formula
return Rsimp((Abs(xn)) (Abs(xd)))
Radd:
-- Addition
-- r1+r2+r3+...
procedure
if Arg() = 0 then say argument
-- Add
do n = 1 to Arg()
xx = Arg(n) 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument n
if \ Datatype(xd,'w') then say argument n
if xd = 0 then say argument n
if n = 1 then do
zn = xn; zd = xd
end
else do
zn = zn*xd+zd*xn; zd = zd*xd
end
end
return Rsimp((zn) (zd))
Rational:
-- Are all arguments in Q?
procedure
do n = 1 to Arg()
xx = Arg(n) 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument n
if \ Datatype(xd,'w') then say argument n
if xd = 0 then say argument n
end
return 1
Rceil:
-- Ceiling
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Ceiling on floating value
return Ceil(xn/xd)
Rcontfrac:
-- Continued fraction
procedure
arg a0,an,b1,bn,c
if \ Datatype(a0,'w') then say argument
if \ Datatype(b1,'w') then say argument
if \ Datatype(c,'w') then say argument
if an = '' then
say argument
if bn = '' then
say argument
-- Calculate
zz = 0
do n = c by -1 to 1
interpret 'a =' an
if n = 1 then
b = b1
else
interpret 'b =' bn
zz = b/(a+zz)
end
return a0+zz
Rcube:
-- Cube
-- r^3
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Formula
return Rsimp((xn*xn*xn) (xd*xd*xd))
Rden:
-- Denominator
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
return (xd)
Rdiv:
-- Division
-- r1/r2/r3/...
procedure
if Arg() = 0 then say argument
-- Divide
do n = 1 to Arg()
xx = Arg(n) 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument n
if \ Datatype(xd,'w') then say argument n
if xd = 0 then say argument n
if n = 1 then do
zn = xn; zd = xd
end
else do
zn = zn*xd; zd = zd*xn
end
end
return Rsimp((zn) (zd))
Req:
-- Equal?
procedure
arg xx,yy; xx = xx 1; yy = yy 1; parse var xx xn xd .; parse var yy yn yd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
if \ Datatype(yn,'w') then say argument
if \ Datatype(yd,'w') then say argument
if yd = 0 then say argument
-- r1 = r2?
return (xn*yd = xd*yn)
Rfloat:
-- Rational -> Float
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Divide
return xn/xd
Rfloor:
-- Floor
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Floor on floating value
return Floor(xn/xd)
Rge:
-- Greater than or equal?
procedure
arg xx,yy
-- r1 >= r2?
return \ Rlt(xx,yy)
Rgt:
-- Greater than?
procedure
arg xx,yy; xx = xx 1; yy = yy 1; parse var xx xn xd .; parse var yy yn yd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
if \ Datatype(yn,'w') then say argument
if \ Datatype(yd,'w') then say argument
if yd = 0 then say argument
-- r1 > r2?
return (xn*yd > xd*yn)
Rinv:
-- Inversion
-- 1/r
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if xn = 0 then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Reverse
return Rsimp((xd) (xn))
Rle:
-- Less than or equal?
procedure
arg xx,yy
-- r1 <= r2?
return \ Rgt(xx,yy)
Rlst2form:
-- List -> Formula
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Compose formula
return (xn)||'/'||(xd)
Rlt:
-- Less than
procedure
arg xx,yy; xx = xx 1; yy = yy 1; parse var xx xn xd .; parse var yy yn yd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
if \ Datatype(yn,'w') then say argument
if \ Datatype(yd,'w') then say argument
if yd = 0 then say argument
-- r1 < r2?
return (xn*yd < xd*yn)
Rmax:
-- Maximum
-- max(r1,r2,r3,...)
procedure
if Arg() = 0 then say argument
-- Find maximum
do n = 1 to Arg()
xx = Arg(n) 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument n
if \ Datatype(xd,'w') then say argument n
if xd = 0 then say argument n
if n = 1 then do
zn = xn; zd = xd
end
else do
if xn*zd > xd*zn then do
zn = xn; zd = xd
end
end
end
return Rsimp((zn) (zd))
Rmin:
-- Minimum
-- min(r1,r2,r3,...)
procedure
if Arg() = 0 then say argument
-- Find minimum
do n = 1 to Arg()
xx = Arg(n) 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument n
if \ Datatype(xd,'w') then say argument n
if xd = 0 then say argument n
if n = 1 then do
zn = xn; zd = xd
end
else do
if xn*zd < xd*zn then do
zn = xn; zd = xd
end
end
end
return Rsimp((zn) (zd))
Rmod:
-- Modulo division
-- r1-r2*floor(r1/r2)
procedure
arg xx,yy; xx = xx 1; yy = yy 1; parse var xx xn xd .; parse var yy yn yd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
if \ Datatype(yn,'w') then say argument
if yn = 0 then say argument
if \ Datatype(yd,'w') then say argument
if yd = 0 then say argument
-- Formula
return Rsub(xx,Rmul(yy,Floor(Rfloat(xx)/Rfloat(yy))))
Rmul:
-- Multiplication
-- r1*r2*r3*...
procedure
if Arg() = 0 then say argument
-- Multiply
do n = 1 to Arg()
xx = Arg(n) 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument n
if \ Datatype(xd,'w') then say argument n
if xd = 0 then say argument n
if n = 1 then do
zn = xn; zd = xd
end
else do
zn = zn*xn; zd = zd*xd
end
end
return Rsimp((zn) (zd))
Rne:
-- Not equal
procedure
arg xx,yy
-- r1 <> r2?
return \ Req(xx,yy)
Rneg:
-- Negation
-- -r
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Negate
return Rsimp((-xn) (xd))
Rnegative:
-- Less than zero?
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- r1 < 0?
return (xn*xd < 0)
Rnum:
-- Numerator
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Numerator
return (xn)
Rperiod:
-- Length of repeating decimals
procedure
arg xx
zz = Rrepetend(xx)
if zz = 0 then
return 0
else
return Length(zz)
Rperiodinv:
-- Length of repeating decimals 1/x
procedure
arg xx
if \ Datatype(xx,'w') then say argument
if xx = 0 then say argument
-- Fast
if xx < 3 then
return 0
-- Recurring
r = 1
do xx
r = 10*r//xx
end
s = r
do zz = 1 until r = s
r = 10*r//xx
end
return zz
Rpositive:
-- Greater than zero?
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- r1 > 0?
return (xn*xd > 0)
Rpow:
-- Integer exponentiation
-- r^n, n in Z
procedure
arg xx,yy; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
if \ Datatype(yy,'w') then say argument
-- Formula
if yy < 0 then
return Rpow(Rinv(xx),-yy)
else
return Rsimp((xn**yy) (xd**yy))
Rquartic:
-- Quartic
-- r^4
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Formula
return Rsimp((xn*xn*xn*xn) (xd*xd*xd*xd))
Rquot:
-- Integer quotient
-- r%n
procedure
arg xx,yy; xx = xx 1; yy = yy 1; parse var xx xn xd .; parse var yy yn yd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
if \ Datatype(yn,'w') then say argument
if yn = 0 then say argument
if \ Datatype(yd,'w') then say argument
if yd = 0 then say argument
-- Formula
return Rfloat(xx)%Rfloat(yy)
Rrat:
-- Float -> Rational
procedure
arg xx
if \ Datatype(xx,'n') then say argument
-- Starting values
in = xx; d = Digits()-1; h = 1'E'd
zn = 0; zd = 1; tn = 1; td = 0
-- Up to precision
do while tn <= h & td <= h
-- Calculate numerator and denominator
x = Trunc(xx)
y = tn; tn = x*tn+zn; zn = y
y = td; td = x*td+zd; zd = y
-- Check precision
if x = xx | tn/td = in then do
if tn > h | td > h then
leave
-- Results
zn = tn; zd = td
leave
end
xx = 1/(xx-x)
end
return Rsimp((zn) (zd))
Rrepetend:
-- Repeating decimals
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Long division
r = xn//xd; r. = ''; p = 1; d = ''
do while r > 0
if r.r <> '' then
return Substr(d,r.r)
r.r = p; r = r*10
a = r%xd; d = d||a; r = r//xd
p = p+1
end
return 0
Rsimp:
-- Simplification
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Simplify
if xd < 0 then do
xn = -xn; xd = -xd
end
g = Gcd(xn,xd)
return (xn/g) (xd/g)
Rsquare:
-- Square
-- r^2
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- Formula
return Rsimp((xn*xn) (xd*xd))
Rsub:
-- Subtraction
-- r1-r2-r3-...
procedure
if Arg() = 0 then say argument
-- Subtract
do n = 1 to Arg()
xx = Arg(n) 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument n
if \ Datatype(xd,'w') then say argument n
if xd = 0 then say argument n
if n = 1 then do
zn = xn; zd = xd
end
else do
zn = zn*xd-zd*xn; zd = zd*xd
end
end
return Rsimp((zn) (zd))
Rzero:
-- Zero?
procedure
arg xx; xx = xx 1; parse var xx xn xd .
if \ Datatype(xn,'w') then say argument
if \ Datatype(xd,'w') then say argument
if xd = 0 then say argument
-- r1 = 0?
return (xn = 0)
-- Module Roots.inc - 22 Mar 2025
-- Solvers for real and complex roots of polynomial equations
-- Real coefficients are coded as string, highest first
-- Example ax^3+cx = 'a 0 c 0'
Ccbeq:
-- Complex roots of cubic equation
-- az^3+bz^2+cz+d = 0 with real coefs
procedure expose cbrt. glob.
arg xx; xx = xx 0 0 0; parse var xx a b c d .
if \ Datatype(a,'n') then say argument
if a = 0 then say argument
if \ Datatype(b,'n') then say argument
if \ Datatype(c,'n') then say argument
if \ Datatype(d,'n') 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(0.25*b2*b2+a2*a2*a2/27,0.5*Digits())
-- Roots
cbrt. = 0
select
when s < 0 then do
h1 = Abs(a2)/3
f = Arccos(-b2/(2*Sqrt(h1*h1*h1)))
h1 = 2*Sqrt(h1); h2 = f/3; h3 = Pi()/3; h4 = a1/3
cbrt.root.1 = h1*Cos(h2)-h4
cbrt.root.2 = -h1*Cos(h2-h3)-h4
cbrt.root.3 = -h1*Cos(h2+h3)-h4
end
when s = 0 then do
h1 = Cbrt(-0.5*b2); h2 = a1/3
cbrt.root.1 = 2*h1-h2
cbrt.root.2 = -h1-h2
cbrt.root.3 = cbrt.root.2
end
when s > 0 then do
h1 = 0.5*b2
f = Sqrt((h1)**2+(a2*a2*a2/27)); g = Cbrt(-h1+f); h = Cbrt(-h1-f)
h1 = g+h; h2 = -0.5*h1; h3 = a1/3; h4 = 0.5*Sqrt(3)*(g-h)
cbrt.root.1 = h1-h3
cbrt.root.2 = (h2-h3) (h4)
cbrt.root.3 = (h2-h3) (-h4)
end
end
-- Discard roundoff digits
do i = 1 to 3
cbrt.root.i = Cround(cbrt.root.i,Digits()-4)
end
numeric digits Digits()/2
-- Normalize
do i = 1 to 3
cbrt.root.i = Cnorm(cbrt.root.i)
end
-- Number of roots
cbrt.0 = 3
return 3
Cqteq:
-- Complex roots of quartic equation
-- az^4+bz^3+cz^2+dx+e = 0 with real coefs
procedure expose qtrt. glob.
arg xx; xx = xx 0 0 0 0
parse var xx a b c d e .
if \ Datatype(a,'n') then say argument
if a = 0 then say argument
if \ Datatype(b,'n') then say argument
if \ Datatype(c,'n') then say argument
if \ Datatype(d,'n') then say argument
if \ Datatype(e,'n') 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 = Cbeq((1) (-a2) (a1*a3-4*a0) (4*a0*a2-a1**2-a0*a3**2))
-- Use max root
u1 = cbrt.root.1
do i = 2 to n
u1 = Max(cbrt.root.i,u1)
end
-- Compute coefficients square equations
h = Sqrt(Round(0.25*a3**2+u1-a2,Digits()-2)); p1 = 0.5*a3+h; p2 = 0.5*a3-h
h = Sqrt(Round(0.25*u1**2-a0,Digits()-2)); q1 = 0.5*u1+h; q2 = 0.5*u1-h
if Round(p1*q2+p2*q1-a1,0.5*Digits()) <> 0 then
parse value q2 q1 with q1 q2
-- Find roots by solving ax^2+bx+c for complex roots
qtrt. = 0
call Csqeq 1 p1 q1
qtrt.root.1 = sqrt.root.1
qtrt.root.2 = sqrt.root.2
call Csqeq 1 p2 q2
qtrt.root.3 = sqrt.root.1
qtrt.root.4 = sqrt.root.2
-- Discard roundoff digits
do i = 1 to 4
qtrt.root.i = Cround(qtrt.root.i,Digits()-4)
end
-- Normalize
numeric digits Digits()/2
do i = 1 to 4
qtrt.root.i = Cnorm(qtrt.root.i)
end
-- Number of roots
qtrt.0 = 4
return 4
Csqeq:
-- Complex roots of square equation
-- az^2+bz+c = 0 with real coefs
procedure expose sqrt. glob.
arg xx; xx = xx 0 0; parse var xx a b c .
if \ Datatype(a,'n') then say argument
if a = 0 then say argument
if \ Datatype(b,'n') then say argument
if \ Datatype(c,'n') then say argument
-- Abc formula
numeric digits Digits()+5
-- Discriminant
s = Round(b*b-4*a*c,Digits()-3)
-- Roots
sqrt. = 0; h1 = -1/(2*a)
select
when s < 0 then do
h2 = Sqrt(-s)
sqrt.root.1 = (h1*b) (h1*h2)
sqrt.root.2 = (h1*b) (-h1*h2)
end
when s = 0 then do
sqrt.root.1 = h1*b
sqrt.root.2 = sqrt.root.1
end
when s > 0 then do
h2 = Sqrt(s)
sqrt.root.1 = h1*(b+h2)
sqrt.root.2 = h1*(b-h2)
end
end
-- Discard roundoff digits
do i = 1 to 2
sqrt.root.i = Cround(sqrt.root.i,Digits()-3)
end
numeric digits Digits()-5
-- Normalize
do i = 1 to 2
sqrt.root.i = Cnorm(sqrt.root.i)
end
-- Number of roots
sqrt.0 = 2
return 2
Cbeq:
-- Real roots of cubic equation
-- ax^3+bx^2+cx+d = 0
procedure expose cbrt. glob.
arg xx; xx = xx 0 0 0 0
parse var xx a b c d .
if \ Datatype(a,'n') then say argument
if a = 0 then say argument
if \ Datatype(b,'n') then say argument
if \ Datatype(c,'n') then say argument
if \ Datatype(d,'n') 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
cbrt. = 0
select
when s < 0 then do
h1 = Abs(a2)/3
f = Arccos(-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; cbrt.root.zz = x1
if x2 <> x1 then do
zz = zz+1; cbrt.root.zz = x2
end
if x3 <> x1 & x3 <> x2 then do
zz = zz+1; cbrt.root.zz = x3
end
end
when s = 0 then do
h1 = Cbrt(-0.5*b2); h2 = a1/3
x1 = 2*h1-h2; x2 = -h1-h2
zz = 1; cbrt.root.zz = 2*h1-h2
if x2 <> x1 then do
zz = zz+1; cbrt.root.zz = -h1-h2
end
end
when s > 0 then do
h1 = 0.5*b2
f = Sqrt((h1)**2+(a2*a2*a2/27)); g = Cbrt(-h1+f); h = Cbrt(-h1-f)
h1 = g+h; h3 = a1/3
zz = 1; cbrt.root.zz = h1-h3
end
end
-- Normalize
numeric digits Digits()/2
do i = 1 to zz
cbrt.root.i = Round(cbrt.root.i,Digits()-2)
end
-- Number of roots
cbrt.0 = zz
return zz
Lieq:
-- Real roots of linear equation
-- ax+b = 0
procedure expose lirt.
arg xx; xx = xx 0 0
parse var xx a b .
if \ Datatype(a,'n') then say argument
if a = 0 then say argument
if \ Datatype(b,'n') then say argument
-- Solution = -b/a
numeric digits Digits()*2
lirt. = 0; lirt.root.1 = -b/a
numeric digits Digits()/2
-- Normalize
lirt.root.1 = lirt.root.1+0
-- Number of roots
lirt.0 = 1
return 1
Qteq:
-- Real roots of quartic equation
-- az^4+bz^3+cz^2+dx+e = 0 with real coefs
procedure expose qtrt. glob.
arg xx; xx = xx 0 0 0 0
parse var xx a b c d e .
if \ Datatype(a,'n') then say argument
if a = 0 then say argument
if \ Datatype(b,'n') then say argument
if \ Datatype(c,'n') then say argument
if \ Datatype(d,'n') then say argument
if \ Datatype(e,'n') 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 = Cbeq((1) (-a2) (a1*a3-4*a0) (4*a0*a2-a1**2-a0*a3**2))
-- Use max root
u1 = cbrt.root.1
do i = 2 to n
u1 = Max(cbrt.root.i,u1)
end
-- Compute coefficients square equations
h = Sqrt(Round(0.25*a3**2+u1-a2,Digits()-2)); p1 = 0.5*a3+h; p2 = 0.5*a3-h
h = Sqrt(Round(0.25*u1**2-a0,Digits()-2)); q1 = 0.5*u1+h; q2 = 0.5*u1-h
if Round(p1*q2+p2*q1-a1,0.5*Digits()) <> 0 then
parse value q2 q1 with q1 q2
-- Find roots by solving ax^2+bx+c for real roots
qtrt. = 0; zz = 0
call Sqeq 1 p1 q1
do i = 1 to sqrt.0
zz = zz+1; qtrt.root.zz = sqrt.root.i
end
call Sqeq 1 p2 q2
do i = 1 to sqrt.0
zz = zz+1; qtrt.root.zz = sqrt.root.i
end
qtrt.0 = zz
-- Discard roundoff digits
do i = 1 to zz
qtrt.root.i = Round(qtrt.root.i,Digits()-4)
end
-- Normalize
numeric digits Digits()/2
do i = 1 to zz
qtrt.root.i = qtrt.root.i/1
end
-- Number of roots
return zz
Sqeq:
-- Real roots of square equation
-- ax^2+bx+c = 0
procedure expose sqrt.
arg xx; xx = xx 0 0 0
parse var xx a b c .
if \ Datatype(a,'n') then say argument
if a = 0 then say argument
if \ Datatype(b,'n') then say argument
if \ Datatype(c,'n') 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
sqrt.root.1 = h1*b
end
when d > 0 then do
zz = 2; h2 = Sqrt(d)
sqrt.root.1 = h1*(b+h2)
sqrt.root.2 = h1*(b-h2)
end
end
sqrt.0 = zz
numeric digits Digits()-2
-- Normalize
do i = 1 to zz
sqrt.root.i = Trunc(sqrt.root.i,Digits())/1
end
-- Number of roots
return zz
-- Module Sequences.inc - 00 Xxx 9999
-- Generates and saves number sequences
-- Results are stored in 4-letter named stems <ssss.>
-- <ssss>.0 holds the number of entries
Abundants:
-- Abundant numbers
procedure expose abun.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
abun. = 0
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.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.zz = i
end
end
abun.0 = zz
return zz
Additives:
-- Additive primes
procedure expose addi. prim.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
addi. = 0
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.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.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.zz = q
end
end
-- Return number of additive primes
addi.0 = zz
return zz
Amicables:
-- Amicable numbers
procedure expose glob. amic.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Scan for amicable pairs
amic. = 0; 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.1.zz = s; amic.2.zz = i
end
end
amic.0 = zz
return zz
Arithmetics:
-- Arithmetic numbers
procedure expose arit. divi.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
arit. = 0
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.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.zz = i
end
end
arit.0 = zz
return zz
Bernoullis:
-- Bernoulli numbers
procedure expose bern. glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- From generating function
numeric digits Max(Digits(),xx+xx)
bern. = 0; bern.0 = 1; bern.1 = -0.5
do n = 2 by 2 to xx
s = 0; n1 = n+1
do k = 0 to n-1
s = s+bern.k*Comb(n1,k)
end
bern.n = -s/n1
end
bern.0 = xx
return xx
Carmichaels:
-- Carmichael 3 strong primes
procedure expose carm.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Janeson
carm. = 0; 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.1.zz = p1; carm.2.zz = p2; carm.3.zz = p3
end
end
end
carm.0 = zz
-- Return count
return zz
Catalans:
-- Catalan numbers
procedure expose cata.
arg xx
if \ Datatype(xx,'n') then say argument
if xx = 0 then say argument
-- Count or threshold?
if xx < 0 then do
xm = Maxnumber(); nm = Abs(xx)
numeric digits nm
end
else do
xm = xx; nm = Maxnumber()
numeric digits Xpon(xm)+2
end
-- Recurring
cata. = 0; c = 1
do zz = 1 to nm until c > xm
c = c*(4*zz-2)/(zz+1); cata.zz = c
end
zz = zz-1; cata.0 = zz
return zz
Chowlas:
-- Chowla numbers
procedure expose chow.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Call aliquot
chow. = 0
do i = 1 to xx
chow.i = Aliquot(i)-1
end
chow.0 = xx
-- Return count
return xx
Combinations:
-- Combinations
procedure expose comb.
arg xx
if \ Datatype(xx,'w') then say argument
if xx = 0 then say argument
-- Recurring definition
comb. = 1
-- Comb(xx,n) for n = 1...xx
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
-- Comb(m,n) for m = 1...xx n = 1...xx
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 numbers = not prime
procedure expose comp.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
comp. = 0
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.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.zz = i
end
end
comp.0 = zz
return zz
Cubans:
-- Cuban primes
procedure expose cuba.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Generate
cuba. = 0; zz = 0
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.zz = v
end
a = b; c = c+1; b = c*c*c
end
cuba.0 = zz
return zz
Cubics:
-- Cubic primes
procedure expose cubi. flag.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Get primes
cubi. = 0; cubi.1 = 2; zz = 1
call Primes xx
-- Generate
a = 2; b = 3; k = 1
do while b <= xx
b = a + k*k*k
if flag.b = 1 then do
zz = zz+1; cubi.zz = b
a = b; k = 1
end
k = k+1
end
cubi.0 = zz
return zz
Cyclops:
-- Cyclop numbers
procedure expose cycl.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Generate
cycl. = 0; m = 0; zz = 1
do f = 1
h = m+1; m = zz
do i = 1 to 9
do j = h to m
a = cycl.j
do k = 1 to 9
b = i||a||k
if b > xx then
leave f
zz = zz+1; cycl.zz = b
end
end
end
end
cycl.0 = zz
return zz
Deficients:
-- Deficient numbers
procedure expose defi.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
defi. = 0
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.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.zz = i
end
end
defi.0 = zz
return zz
Divisors:
-- Divisors of an integer
procedure expose divi. wrkl. wrkr.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Fast
divi. = 0
if xx = 1 then do
divi.1 = 1; divi.0 = 1
return 1
end
-- Euclid's method
a = 1; wrkl.1 = 1; b = 1; wrkr.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; wrkl.a = j; b = b+1; wrkr.b = xx%j
end
end
if j*j = xx then do
a = a+1; wrkl.a = j
end
-- Save in table
zz = 0
do i = 1 to a
zz = zz+1; divi.zz = wrkl.i
end
do i = b by -1 to 1
zz = zz+1; divi.zz = wrkr.i
end
divi.0 = zz
-- Return number of divisors
return zz
Efactors:
-- Prime factors with exponent
procedure expose efac.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
efac. = 0
if xx = 1 then
return 0
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
procedure expose emir. flag.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Get primes
emir. = 0; zz = 0
call Primes xx
-- Generate
do i = 13 by 2 to xx
a = Reverse(i)
if a = i then
iterate i
if \ flag.i then
iterate i
if \ flag.a then
iterate i
zz = zz+1; emir.zz = i
end
emir.0 = zz
return zz
Erdoss:
-- Erdos primes
procedure expose erdo. prim. flag. glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Get primes
erdo. = 0; zz = 0
call Primes xx
-- Generate
do i = 1 to prim.0
a = prim.i
do j = 1
k = Fact(j)
if k >= a then
leave j
p = a-k
if flag.p then
iterate i
end
zz = zz+1; erdo.zz = a
end
erdo.0 = zz
return zz
Euclids:
-- Euclid-Mullin numbers
procedure expose eucl.
arg xx
numeric digits 100
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
if xx > 17 then say argument
-- Using Ffactor = first prime factor
eucl. = 0; eucl.1 = 2; eucl.0 = 1
p = 2
do i = 2 to xx
z = p+1; t = Ffactor(z); eucl.i = t; p = p*t
end
-- Save and return number
eucl.0 = xx
return xx
Extras:
-- Extra primes
procedure expose extr.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Generate
extr. = 0; extr.1 = 2; zz = 1
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.zz = i
end
extr.0 = zz
return zz
Factors:
-- Prime factors
procedure expose fact. glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 2 then say argument
-- Fast
fact. = 0
if Prime(xx) then do
fact.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.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.zz = j
xx = xx%j
end
end
if p = 3 then
iterate
k = j+2
do while xx//k = 0
zz = zz+1; fact.zz = k
xx = xx%k
end
end
-- Last factor
if xx > 1 then do
zz = zz+1; fact.zz = xx
end
fact.0 = zz
-- Return number of factors
return zz
Fareys:
-- Farey fractions
procedure expose fare.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Recurring
fare. = 0; fare.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.zz = aa'/'bb
end
fare.0 = zz
-- Number of entries
return zz
Fibonaccis:
-- Fibonacci numbers
procedure expose fibo.
arg xx
if \ Datatype(xx,'w') then say argument
-- Count or threshold?
if xx < 0 then do
xm = Maxnumber(); nm = Abs(xx)
numeric digits nm%2
end
else do
xm = xx; nm = Maxnumber()
numeric digits xpon(xm)+2
end
-- Fast
fibo. = 0
if xm = 0 then
return 0
fibo.1 = 1
if xm = 1 | nm = 1 then do
fibo.0 = 1
return 1
end
-- Recurring
b = 1; c = 1
do zz = 2 until zz = nm | c > xm
fibo.zz = c; a = b; b = c; c = a+b
end
fibo.0 = zz
return zz
Frobeniuss:
-- Frobenius primes
procedure expose frob. prim.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Get primes
frob. = 0; zz = 0
p = Primes(xx%10)
-- Generate
do i = 1 to p-1
j = i+1; f = prim.i * prim.j - prim.i - prim.j
if f > xx then
leave
zz = zz+1; frob.zz = f
end
frob.0 = zz
return zz
Giugas:
-- Giuga numbers
procedure expose giug.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
giug. = 0
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.zz = w
end
giug.0 = zz
return zz
Hammings:
-- Hamming numbers
procedure expose hamm.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Ensure enough digits
hamm. = 1
numeric digits 2**(Length(Std(xx))+1)
-- Dijkstra
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.zz = h
if zz = xx then
leave
if x2 = h then do
i2 = i2+1; x2 = hamm.i2+hamm.i2
end
if x3 = h then do
i3 = i3+1; x3 = hamm.i3+hamm.i3+hamm.i3
end
if x5 = h then do
i5 = i5+1; x5 = hamm.i5*5
end
end
hamm.0 = zz
return zz
Highcomposites:
-- Highly composite numbers
procedure expose high.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Thresholds and increments
high. = 0
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
-- Collect 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.zz = j
m = d
end
end
end
high.0 = zz
-- Return count
return zz
Humbles:
-- Humble numbers
procedure expose humb.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Ensure enough digits
humb. = 1
numeric digits 2**(Length(xx)+1)
-- Dijkstra
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.zz = h
if zz = xx then
leave
if x2 = h then do
i2 = i2+1; x2 = humb.i2+humb.i2
end
if x3 = h then do
i3 = i3+1; x3 = humb.i3+humb.i3+humb.i3
end
if x5 = h then do
i5 = i5+1; x5 = humb.i5*5
end
if x7 = h then do
i7 = i7+1; x7 = humb.i7*7
end
end
humb.0 = zz
return zz
Kaprekars:
-- Kaprekar numbers
procedure expose kapr.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
kapr. = 0
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.zz = w
end
zz = zz-1; kapr.0 = zz
return zz
end
-- Ensure enough digits
xx = xx+1
p = Max(Digits(),2*Length(xx))
numeric digits p
zz = 1; kape.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.zz = i
leave
end
end
end
kapr.0 = zz
return zz
Ludics:
-- Ludic numbers
procedure expose ludi. work.
arg xx
if \ Datatype(xx,'n') then say argument
if xx < 1 then say argument
-- Use a sparse array
work. = 1
do i = 2 to xx%2
if work.i then do
n = 0
do j = i+1 to xx
if work.j then do
n = n+1
if n//i = 0 then do
work.j = 0
end
end
end
end
end
-- Save results
zz = 0
do i = 1 to xx
if work.i then do
zz = zz+1; ludi.zz = i
end
end
-- Count
ludi.0 = zz
return zz
Magics:
-- Magic numbers
procedure expose magi.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Formula
magi. = 0
do zz = 1 until m > xx
m = Magic(zz); magi.zz = m
end
magi.0 = zz
return zz
Magnanimouss:
-- Magnanimous numbers
procedure expose magn. flag.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 0 then say argument
-- Get primes below xx
call Primes xx
magn. = 0; zz = 0
do i = 0 to xx
-- 0...9 always apply
if i < 10 then do
zz = zz+1; magn.zz = i
iterate i
end
-- Numbers having parity do not apply
if i > 1001 then do
parse var i 1 l 2 '' -1 r
if l//2 = r//2 then
iterate i
end
-- Generate candidates and test primality
do j = 1 to Length(i)-1
parse var i 1 l +(j) r
s = l+r
if \ flag.s then
iterate i
end
zz = zz+1; magn.zz = i
end
magn.0 = zz
return zz
Motzkins:
-- Motzkin numbers
procedure expose motz.
arg xx
if \ Datatype(xx,'w') then say argument
if xx = 0 then say argument
-- Fast
motz. = 0; motz.0 = 1; motz.1 = 1; motz.0 = 1
if xx = 1 then
return 1
-- Recurring
a = 1; b = 1; c = 0
do n = 2 while c < xx
c = ((3*n-3)*a+(2*n+1)*b)/(n+2)
motz.n = c
a = b; b = c
end
motz.0 = n-1
return motz.0
Perfects:
-- Perfect numbers
procedure expose perf.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
perf. = 0
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.zz = w
end
zz = zz-1; perf.0 = zz
return zz
Practicals:
-- Practical numbers
procedure expose prac. fact.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
prac. = 0
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.zz = w
end
zz = zz-1; prac.0 = zz
return zz
end
-- Using function practical()
zz = 1; prac.1 = 1
do i = 2 by 2 to xx
if Practical(i) then do
zz = zz+1; prac.zz = i
end
end
prac.0 = zz
return zz
Primes:
-- Primes
procedure expose prim. work. flag. glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx = 0 then say argument
-- Fast
prim. = 0; flag. = 0
if xx = 1 then
return 0
-- Nth prime or threshold?
if xx < 0 then
xx = Primeest(Abs(xx))
-- Sieve of Eratosthenes odd integers
work. = 1
do i = 3 by 2 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 and flag results
prim.1 = 2; flag.2 = 1; zz = 1
do i = 3 by 2 to xx
if work.i then do
zz = zz+1; prim.zz = i; flag.i = 1
end
end
prim.0 = zz
return zz
Primorials:
-- Primorials
procedure expose prim. prmo. glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx = 0 then say argument
if xx < -50000 then say argument
if xx > 1e250000 then say argument
-- Get primes
numeric digits Max(Digits(),Xpon(xx)+1)
if xx < 0 then
call Primes(xx)
else
call Primes(600000)
-- Multiply primes
prmo. = 0
p = 1; zz = 0
do i = 1 to prim.0
numeric digits xpon(p)+6
p = p*prim.i
if xx > 0 then
if p > xx then
leave
zz = zz+1; prmo.zz = p
end
prmo.0 = zz
return zz
Quadratics:
-- Quadratic primes
procedure expose quad. flag.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Get primes
quad. = 0; quad.1 = 2; zz = 1
call Primes xx
-- Generate
a = 2; b = 3; k = 1
do while b <= xx
b = a + k*k
if flag.b = 1 then do
zz = zz+1; quad.zz = b
a = b; k = 1
end
k = k+1
end
quad.0 = zz
return zz
Reversables:
-- Reversable primes
procedure expose reve. prim. flag.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Get primes
reve. = 0; zz = 0
e = Xpon(xx)+1; p = Primes(1'E'e)
-- Generate
do i = 1 to p
a = prim.i
if a > xx then
leave i
b = Reverse(a)
if \ flag.b then
iterate i
zz = zz+1; reve.zz = a
end
reve.0 = zz
return zz
Smooths:
-- Smooth numbers
procedure expose prim. smoo. numb. indi.
arg xx,yy
if \ Datatype(xx,'n') then say argument
if Abs(xx) < 1 then say argument
if \ Prime(yy) then say argument
-- Count or threshold?
if xx < 0 then do
xm = Maxnumber(); nm = Abs(xx)
end
else do
xm = xx; nm = Maxnumber()
end
-- Get and number primes
call Primes yy
numb. = 0
do i = 1 to prim.0
p = prim.i; numb.p = i
end
-- Collect smooth numbers
smoo. = 0; smoo.1 = 1; smoo.0 = 1; indi. = 1
n = numb.yy
do j = 2 to nm
i = indi.1; z = prim.1*smoo.i
do k = 2 to n
i = indi.k; v = prim.k*smoo.i
if v < z then
z = v
end
if z > xm then
leave j
smoo.j = z
do d = 1 to n
i = indi.d
if prim.d*smoo.i = z then
indi.d = indi.d+1
end
end
zz = j-1; smoo.0 = zz
return zz
Squarefrees:
-- Square free numbers
procedure expose squa. work. prim. glob. flag.
arg xx
if \ Datatype(xx,'w') then say argument
if xx = 0 then say argument
-- Fast
squa. = 0
if xx = 1 then do
squa.1 = 1; flag.1 = 1; squa.0 = 1
return 1
end
-- Precision
numeric digits Max(Digits(),Xpon(xx)+1)
-- Get primes
n = Primes(Isqrt(xx))
-- Get rid of multiples of squared primes
work. = 1
do i = 1 to n
p = prim.i; p = p*p
do j = p by p to xx
work.j = 0
end
end
-- Save results
zz = 0
do i = 1 to xx
if work.i then do
zz = zz+1; squa.zz = i; flag.i = 1
end
end
squa.0 = zz
return zz
Squarefrees:
-- Square free numbers
procedure expose squa. work. prim. glob.
arg xx
if \ Datatype(xx,'w') then say argument
if xx = 0 then say argument
-- Fast
squa. = 0
if xx = 1 then do
squa.free.1 = 1; squa.flag.1 = 1; squa.0 = 1
return 1
end
-- Precision
numeric digits Max(Digits(),Xpon(xx)+1)
-- Get primes
n = Primes(Isqrt(xx))
-- Get rid of multiples of squared primes
work. = 1
do i = 1 to n
p = prim.i; p = p*p
do j = p by p to xx
work.j = 0
end
end
-- Save results
zz = 0
do i = 1 to xx
if work.i then do
zz = zz+1; squa.free.zz = i; squa.flag.i = 1
end
end
squa.0 = zz
return zz
Totients:
-- Euler's totient numbers
procedure expose toti.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Recurring sequence
toti. = 0
do i = 1 to xx
toti.i = i
end
do i = 2 to xx
if toti.i < i then
iterate i
do j = i by i to xx
toti.j = toti.j-toti.j/i
end
end
toti.0 = xx
return xx
Ufactors:
-- Unique prime factors
procedure expose ufac.
arg xx
if \ Datatype(xx,'w') then say argument
if xx < 1 then say argument
-- Fast
ufac. = 0
if xx = 1 then
return 0
if xx < 4 then do
ufac.1 = xx; ufac.0 = 1
return 1
end
if Prime(xx) then do
ufac.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.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.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.zz = yy
end
end
-- Last factor
if xx > 1 then do
zz = zz+1; ufac.zz = xx
end
ufac.0 = zz
-- Return number of factors
return zz
-- Module Settings.inc - 28 Jan 2025
-- Settings used by many other modules
call Lines 'dummy'
signal on halt name Abend
signal on notready name Abend
signal on novalue name Abend
signal on syntax name Abend
parse version version; parse source . . source
glob. = ''; call Time('r')