kForth
1 program
Added 2026-03-12T10:00:00Z
Agent: claude-codeModel: claude-sonnet-4-6WebSearch: disabled
Evidence
Report issue
View issues
Aliases: kForth-32, kForth-64
Provenance: commit b1bbe7b616 · authored 2026-03-12T00:19:28+01:00 · agent claude-code · model claude-sonnet-4-6
Sources mentioning this language
1 source · not in taxonomy (canonical name didn't match any upstream)
Related languages
LLM-contributed programs
Pi Spigot Algorithm
Provenance: commit b1bbe7b616 · authored 2026-03-12T00:19:28+01:00 · agent claude-code · model claude-sonnet-4-6 · WebSearch disabled
\ pispigot.4th
\
\ Print pi to arbitrary number of digits
\
\ Obtained from: http://wiki.forthfreak.net/index.cgi?PiSpigot
\
\ Great Computer Language Shootout
\ http://shootout.alioth.debian.org/
\ contributed by Albert van der Horst, Ian Osgood
\ modified to run under kForth by K. Myneni, 27Jan06; rev 28Jan06
\ ==== kForth requires ===================
include ans-words
\ =======================================
\ read NUM from last command line argument
\ 0. argc @ 1- arg >number 2drop drop constant NUM
1000 constant NUM \ set number of digits here
\
\ Arbitrary precision arithmetic
\ A p-number consists of a count plus count cells, 2-complement small-endian
\
\ Shorthand.
: p>size ( pn -- size ) POSTPONE @ ; IMMEDIATE
: p>last ( pn -- msb ) DUP p>size CELLS + ;
: [I] POSTPONE I POSTPONE CELLS POSTPONE + ; IMMEDIATE
\ Give sign of p
: p0< ( p -- flag ) p>last @ 0< ;
\ Copy a p-number to another buffer
: pcopy ( src dst -- ) OVER p>size 1+ CELLS MOVE ;
\ Check for overflow, extend the p-number if needed
: ?carry ( carry p -- ) 2DUP p0< <> IF 1 OVER +! p>last ! ELSE 2DROP THEN ;
\ In-place multiply by an unsigned integer
0 value n
0 ptr p
: p* ( { n p -- } ) to p to n
p p0< 0 0 ( sign dcarry )
p p>size 1+ 1 DO
p [I] @ ( digit )
n UM* D+ SWAP ( carry digit )
p [I] ! 0
LOOP
ROT n UM* D+ DROP p ?carry ;
\ Ensure two p-numbers are the same size before adding
0 value n
0 ptr p
0 value sign
: extend OVER p0< ( { p n sign -- } ) to sign to n to p
p p>size 1+ n p +! p p>size 1+ SWAP DO sign p [i] ! LOOP ;
: ?extend ( p1 p2 -- p1 p2 )
OVER p>size OVER p>size - ?DUP IF
DUP 0< IF >R OVER R> NEGATE
ELSE OVER SWAP
THEN extend
THEN ;
\ In-place addition of another p-number
0 ptr src
0 ptr p
: p+ ?extend ( { src p -- } ) to p to src
src p0< p p0< 0 0 ( sign sign dcarry )
p p>size 1+ 1 DO
p [I] @ 0 D+
src [I] @ 0 D+ SWAP
p [I] ! 0
LOOP
DROP + + p ?carry ; \ add signs, check for overflow
\ In-place subtraction of another p-number
0 ptr src
0 ptr p
: p- ?extend ( { src p -- } ) to p to src
src p0< p p0< 0 0 ( sign sign dcarry )
p p>size 1+ 1 DO
p [I] @ 0 D+
src [I] @ 0 D- SWAP
p [I] ! s>d
LOOP
DROP + + p ?carry ; \ add signs, check for overflow
\
\ pi-spigot specific computation
\
\ approximate upper limit on size required (1000 -> 1166)
NUM 6 5 */ 2+ CELLS constant SIZE
\ Current z transformation
CREATE aq SIZE ALLOT 1 1 aq 2!
CREATE ar SIZE ALLOT 0 1 ar 2!
\ "as" identical zero and remains so
CREATE at SIZE ALLOT 1 1 at 2!
\ Generate non zero parts of next matrix ( -- q r t )
VARIABLE K
: generate 1 K +! K @ DUP 2* 1+ DUP 2* SWAP ;
\ temporary p-number buffer
CREATE HERE 1024 1024 * CELLS ALLOT ( comment this line for ANS Forth )
\ Multiply z from the left
: compose< ( bq br bt -- )
DUP at p* ar p* aq HERE pcopy HERE p* HERE ar p+ aq p* ;
\ Multiply z from the right
: compose> ( bt br bq -- )
DUP aq p* ar p* at HERE pcopy HERE p* HERE ar p- at p* ;
\ Calculate z at point 3, leaving integer part and fractional part.
\ Division is by multiple subtraction until the fractional part is
\ negative.
: z(3) ( -- n pfract ) HERE aq OVER pcopy 3 OVER p* ar OVER p+
0 BEGIN SWAP at OVER p- DUP p0< 0= WHILE SWAP 1+ REPEAT ;
\ Calculate z at point 4, based on the result for point 3
\ and decide whether the integer parts are the same.
: z(4)same? ( pfract -- flag ) aq OVER p+ p0< ;
: pidigit ( -- nextdigit)
BEGIN z(3) z(4)same? 0= WHILE DROP generate compose< REPEAT
1 OVER 10 * 10 compose> ;
: printcount ( n -- ) 9 emit [char] : emit 1 U.R CR ;
\ ( digits - remaining)
: printdigit pidigit [CHAR] 0 + EMIT
DUP 10 MOD 0= IF printcount ELSE DROP THEN ;
\ Spigot n digits with formatting ( n --)
: spigot DUP 1+ 1 DO I printdigit LOOP
DUP 10 MOD IF 10 2DUP MOD - SPACES printcount ELSE DROP THEN ;
NUM spigot bye