一百個例題 (81 ~ 85)
Ching-Tang Tseng
Hamilton, New Zealand
3 October 2024
\ Chinese Remainder Theorem
\ simple version
integer i
: test1
basic
10 for i = 1 to 10000000000
20 if ( i mod 11 = 1 ) and ( i mod 13 = 2 )
and ( i mod 15 = 3 ) and ( i mod 17 = 4 )
and ( i mod 19 = 5 )
then 60
30 next i
40 print " Question is inexact! "
50 goto 80
60 run 2drop
70 print " Answer = N * " ; i ; " , N = 1, 2, 3, ... "
80 end ;
\ turbo version: How dose it speeded up? You got to know that.
: test2
basic
10 for i = 19 + 5 to 10000000000 step 19
20 if ( i mod 11 = 1 ) and ( i mod 13 = 2 )
and ( i mod 15 = 3 ) and ( i mod 17 = 4 )
and ( i mod 19 = 5 )
then 60
30 next i
40 print " Question is inexact! "
50 goto 80
60 run 2drop
70 print " Answer = N * " ; i ; " , N = 1, 2, 3, ... "
80 end ;
test1
test2
\ 80386 ciforth 5.1
\ fload chinar.f
\ I : ISN'T UNIQUE
\ Answer = N * 346413 , N = 1, 2, 3, ...
\ Answer = N * 346413 , N = 1, 2, 3, ... OK
\ SFP.F
\ test in wina64 ok 20170616
1 LOAD
WANT DUMP
\ Floating point emulation 11/02 BNE
\ include locals.fth
\ anew floatingpoint
\ ANS Forth using CORE, CORE EXT and DOUBLE wordsets.
\ Rev 0. See bottom for rev history.
\ Floating point representation on floating point stack:
\ 0 upper mantissa
\ 1 lower mantissa
\ 2 exponent: MSB = sign of mantissa, others = signed exponent
10 CONSTANT maxdepth \ *** 8 --> 10
3 CELLS CONSTANT b/float
CREATE fstak maxdepth b/float * ALLOT \ floating point stack
VARIABLE fsp \ stack pointer
VARIABLE sigdigits \ # of digits to display after decimal
VARIABLE ferror \ last seen error
CREATE fpad b/float ALLOT \ temporary float variable
HEX
\ 10000 0= [IF] 10 [ELSE] 20 [THEN] CONSTANT bits/cell \ 16-bit or 32-bit Forth
40 CONSTANT bits/cell \ ***
DECIMAL
bits/cell 1- 602 1000 */ CONSTANT maxdig \ max decimal digits that fit in double
-1 1 RSHIFT DUP CONSTANT &unsign INVERT CONSTANT &sign \ 7F... 80...
&sign 1 RSHIFT CONSTANT &esign \ 40...
\ ------------------------------------------------------------------------------
\ Low level math you could CODE for better speed
\ : DLSHIFT >R SWAP DUP R@ LSHIFT SWAP 8 CELLS R@ - RSHIFT ROT R> LSHIFT OR ; \ ***
\ : DRSHIFT >R DUP R@ RSHIFT SWAP 8 CELLS R@ - LSHIFT ROT R> RSHIFT OR SWAP ; \ ***
\ : D2/ 1 DRSHIFT ; \ ***
HEX
: D2/
DUP 1 AND
IF 2/ SWAP 2/ 8000000000000000 OR SWAP
ELSE 2/ SWAP 2/ 7FFFFFFFFFFFFFFF AND SWAP
THEN
;
DECIMAL
: UD2/ ( d -- d' )
D2/ &unsign AND ;
\ : 0MAX ( n1 -- n2 ) DUP 0 < IF DROP 0 THEN ; \ ***
: frshift ( count 'man -- ) \ right shift mantissa
SWAP 0 MAX bits/cell 2* MIN \ ***
>R DUP 2@ R> 0
?DO UD2/ LOOP ROT 2! ;
: exp>sign ( exp -- exp' sign )
DUP &unsign AND \ mask off exponent
DUP &esign AND 2* OR \ sign extend exponent
SWAP &sign AND ; \ get sign of mantissa
: sign>exp ( exp sign -- exp' )
SWAP &unsign AND OR ;
: +ex ( n1 offset -- n1' ) \ bump n1 but preserve its MSB
SWAP exp>sign >R + R> sign>exp ;
\ : D2* 1 DLSHIFT ; \ ***
: D2* 2DUP D+ ;
: T2* ( triple -- triple' )
D2* ROT DUP 0< 1 AND >R 2* ROT ROT R> 0 D+ ;
: 0<> 0= 0= ; \ ***
: T2/ ( triple -- triple' )
OVER 1 AND 0<> &sign AND >R D2/ ROT \ MHL|C
1 RSHIFT R> OR ROT ROT ;
: 2>R POSTPONE SWAP POSTPONE >R POSTPONE >R ; IMMEDIATE \ ***
: 2R> POSTPONE R> POSTPONE R> POSTPONE SWAP ; IMMEDIATE \ ***
: 2R@ POSTPONE 2R> POSTPONE 2DUP POSTPONE 2>R ; IMMEDIATE \ ***
: T+ ( t1 t2 -- t3 )
2>R >R ROT 0 R> 0 D+ 0 2R> D+
ROT >R D+ R> ROT ROT ;
: *norm ( triple exp -- double exp' ) \ normalize triple
>R BEGIN DUP 0< 0=
WHILE T2* R> 1- >R
REPEAT &sign 0 0 T+ \ round
ROT DROP R> ;
\ ------------------------------------------------------------------------------
\ Parameter indicies
: 'rx ( ofs -- addr ) fsp @ 3 * + CELLS fstak + ;
: 'm1 ( -- addr ) -3 'rx ; \ -> 1st stack mantissa
: 'm2 ( -- addr ) -6 'rx ; \ -> 2nd stack mantissa
: 'm3 ( -- addr ) -9 'rx ; \ -> 3rd stack mantissa \ *** -6 -->-9
: 'e1 ( -- addr ) -1 'rx ; \ -> 1st stack exponent
: 'e2 ( -- addr ) -4 'rx ; \ -> 2nd stack exponent
: 'e3 ( -- addr ) -7 'rx ; \ -> 3nd stack exponent \ *** added
: fmove ( a1 a2 -- ) b/float MOVE ;
: m1get ( addr -- ) 'm1 fmove ; \ move to M1
: m1sto ( addr -- ) 'm1 SWAP fmove ; \ move from M1
: expx1 ( -- exp sign ) 'e1 @ exp>sign ;
: expx2 ( -- exp sign ) 'e2 @ exp>sign ;
\ ------------------------------------------------------------------------------
\ For testing:
\ : f? 'm1 2@ UD2/ D>F expx1 IF FNEGATE THEN
\ &sign OR 1+ S>F 2e0 FLN f* FEXP F* FS. ;
\ 20 SET-PRECISION : f?? FSWAP f? FSWAP f? ;
\ : fd fstak fsp @ b/float * DUMP ; \ dump stack
\ ------------------------------------------------------------------------------
\ A normalized float has an unsigned mantissa with its MSB = 1
: normalize ( -- )
'm1 2@ 2DUP OR 0=
IF 2DROP \ Zero is a special case.
ELSE expx1 >R >R
BEGIN DUP 0< 0= \ not normalized?
WHILE D2* R> 1- >R \ shift mantissa left
REPEAT 'm1 2!
R> R> sign>exp 'e1 !
THEN ;
\ ------------------------------------------------------------------------------
\ Floating Point Words
: F2* ( fs: r1 -- r3 ) 'e1 @ 1 +ex 'e1 ! ;
: F2/ ( fs: r1 -- r3 ) 'e1 @ -1 +ex 'e1 ! ;
: PRECISION ( -- n ) sigdigits @ ;
: SET-PRECISION ( n -- ) maxdig MIN sigdigits ! ;
: FCLEAR ( -- ) 0 fsp ! 0 ferror ! ;
: FDEPTH ( -- ) fsp @ ;
: FDUP ( fs: r -- r r ) 1 fsp +! 'm2 m1get ;
: FDROP ( fs: r -- ) -1 fsp +! ;
: FNEGATE ( fs: r1 -- r3 ) 'e1 @ &sign XOR 'e1 ! ;
: D>F ( d -- | -- r ) FDUP DUP 0< IF DNEGATE &sign ELSE 0 THEN
'e1 ! 'm1 2! normalize ;
: F>D ( -- d | r -- ) expx1 >R DUP &esign AND
IF NEGATE &unsign AND 'm1 frshift 'm1 2@ R> IF DNEGATE THEN
ELSE R> 2DROP -1 &unsign 1 ferror ! \ overflow: return maxdint
THEN FDROP ;
: S>F ( n -- | -- r ) S>D D>F ;
: FLOAT+ ( n1 -- n2 ) b/float + ;
: FLOATS ( n1 -- n2 ) b/float * ;
: F@ ( a -- | -- r ) FDUP m1get ;
: F! ( a -- | r -- ) m1sto FDROP ;
: F0= ( -- t | r -- ) 'm1 2@ OR 0= FDROP ;
: F0< ( -- t | r -- ) 'e1 @ 0< FDROP ;
: FLOOR ( fs: r1 -- r2 ) F>D DUP 0< IF -1 S>D D+ THEN D>F ;
: FABS ( fs: r1 -- r3 ) 'e1 @ 0< IF FNEGATE THEN ;
: FALIGN ( -- ) ALIGN ;
: FALIGNED ( addr -- addr ) ALIGNED ;
: FSWAP ( fs: r1 r2 -- r2 r1 ) 'm1 fpad fmove 'm2 m1get fpad 'm2 fmove ;
: FOVER ( fs: r1 r2 -- r1 r2 r3 ) 1 fsp +! 'm3 m1get ;
\ : FPICK ( n -- ) ( fs: -- r ) 1 fsp +! 1+ -3 * 'rx m1get ;
: FPICK ( n -- ) ( f: -- r )
1 fsp +! 2 + b/float * 'rx m1get ; ( ** was BUG ) \ ***
: FNIP ( fs: r1 r2 -- r2 ) FSWAP FDROP ;
: FROT ( fs: r1 r2 r3 -- r2 r3 r1 )
'm3 fpad fmove 'm2 'm3 b/float 2* MOVE fpad m1get ;
: F+ ( fs: r1 r2 -- r3 )
FDUP F0= IF FDROP EXIT THEN \ r2 = 0
FOVER F0= IF FNIP 'e1 @ 0< IF FNEGATE THEN EXIT THEN \ r1 = 0
expx1 >R expx2 >R - DUP 0<
IF NEGATE 'm1 frshift 0 \ align exponents
ELSE DUP 'm2 frshift
THEN 'e2 @ +
'm2 2@ R> IF DNEGATE -1 ELSE 0 THEN
'm1 2@ R> IF DNEGATE -1 ELSE 0 THEN
T+ DUP >R ( exp L M H | sign )
DUP IF T2/ IF DNEGATE THEN 'm2 2! 1+
ELSE DROP 'm2 2!
THEN R> &sign AND sign>exp 'e2 !
FDROP normalize ;
: F- ( fs: r1 r2 -- r3 ) FNEGATE F+ ;
: F< ( -- t ) ( F: r1 r2 -- ) FOVER FOVER F- F0< ;
: FROUND ( fs: r1 -- r2 )
expx1 >R DUP NEGATE 1- 'm1 frshift \ convert to half steps
'm1 2@ 1 0 D+ \ round
'm1 2! R> sign>exp 'e1 ! normalize ; \ re-float
: FMIN ( F: r1 r2 -- rmin ) FOVER FOVER F<
IF FDROP ELSE FNIP THEN ;
: FMAX ( F: r1 r2 -- rmax ) FOVER FOVER F<
IF FNIP ELSE FDROP THEN ;
\ 1. VALUE
: VALUE
CREATE , \ ( n -- )
DOES> @ \ ( -- n )
;
: VALUES ( N -- )
0 ?DO 0 VALUE LOOP ;
: TO ( N -- )
' >BODY STATE @
IF POSTPONE LITERAL POSTPONE !
ELSE !
THEN ; IMMEDIATE
: +TO ( N -- )
' >BODY STATE @
IF POSTPONE LITERAL POSTPONE +!
ELSE +!
THEN ; IMMEDIATE
0 VALUE L1
0 VALUE U1
0 VALUE L2
0 VALUE U2
: PICK 1+ CELLS DSP@ + @ ; \ ***
: F* ( fs: r1 r2 -- r3 )
'm1 2@ TO U1 TO L1 'm2 2@ TO U2 TO L2 \ { L1 U1 L2 U2 -- } ***
L1 L2 OR
IF L1 L2 UM* &sign 0 D+ NIP \ round
U1 U2 UM*
L1 U2 UM* 0 T+
L2 U1 UM* 0 T+
ELSE 0 U1 U2 UM* \ lower parts are 0
THEN 2DUP OR 3 PICK OR \ zero?
IF expx1 >R expx2 >R + bits/cell 2* + *norm
R> R> XOR sign>exp 'e2 ! 'm2 2!
ELSE DROP D>F \ zero result
THEN FDROP ;
: DU< ROT 2DUP = IF 2DROP U< EXIT THEN 2SWAP 2DROP SWAP U< ; \ ***
: D- ( d1 d2 -- d1-d2 ) DNEGATE D+ ; \ ***
: -ROT ROT ROT ; \ ***
: U> SWAP U< ; \ ***
: F/ ( fs: r1 r2 -- r3 )
FDUP F0=
IF FDROP -1 -1 'm1 2! 2 ferror ! \ div by 0, man= umaxint
'e1 @ &sign AND &sign 2/ 1- OR 'e1 ! \ exponent = maxint/2
ELSE 'm1 2@ 'm2 2@ DU< IF 1 'm2 frshift THEN \ divisor <= dividend
'm1 CELL+ @
IF 'm2 2@ UD2/ 'm1 2@ UD2/ \ max divisor = dmaxint
0 0 PAD 2!
bits/cell 2* 1+ 0 \ long division
DO 2OVER 2OVER DU< \ double/double
IF 0
ELSE 2DUP 2>R D- 2R> 1 \ a b --> a-b b
THEN 0 PAD 2@ D2* D+ PAD 2!
2SWAP D2* 2SWAP
LOOP DU< 0= 1 AND 0 \ round
PAD 2@ D+
bits/cell 2*
ELSE 0 'm2 2@ 'm1 @ DUP >R UM/MOD \ 0 rem quot | divisor
-ROT R@ UM/MOD -ROT R> 1 RSHIFT U> IF 1 0 D+ THEN \ round
bits/cell 2*
THEN expx2 >R expx1 >R - SWAP -
>R 'm2 2! R> R> R> XOR sign>exp 'e2 !
FDROP
THEN ;
: F~ ( f: r1 r2 r3 -- ) ( -- flag ) \ f-proximate
FDUP F0< \ Win32forth version
IF FABS FOVER FABS 3 FPICK FABS F+ F* \ r1 r2 r3*(r1+r2)
FROT FROT F- FABS FSWAP F<
ELSE FDUP F0=
IF FDROP F- F0=
ELSE FROT FROT F- FABS FSWAP F<
THEN
THEN ;
\ For fixed-width fields, it makes sense to use these words for output:
\ fsplit ( F: r -- ) ( fracdigits -- sign Dint Dfrac )
\ Converts to integers suitable for pictured numeric format.
\ Fracdigits is the number of digits to the right of the decimal.
\ .digits ( UD fracdigits -- )
\ Outputs a fixed number of digits
: fsplit ( F: r -- ) ( fracdigits -- sign Dint Dfrac )
>R expx1 NIP FABS \ int part must fit in a double
FDUP F>D 2DUP D>F F- \ get int, leave frac
2 0 R> 0
?DO D2* 2DUP D2* D2* D+ LOOP \ 2 * 10^precision
D>F F* F>D 1 0 D+ UD2/ ; \ round
: .digits ( UD cnt -- )
0 ?DO # LOOP 2DROP ;
\ Nonstandard: PRECISION is the number of digits after the decimal, not the
\ total number of digits.
\ : 0> 0 > ; \ ***
: (F.) ( F: r -- ) ( -- addr len )
<# FDEPTH 0 > 0= IF #> EXIT THEN \ empty stack -> blank \ *** 0< --> 0 <
PRECISION fsplit
PRECISION .digits
PRECISION IF [CHAR] . HOLD THEN
#S SIGN #> ;
: F. ( F: r -- ) (F.) TYPE SPACE ;
: FCONSTANT ( -name- ) ( F: r -- ) \ compile time
( F: -- r ) \ runtime
CREATE HERE F! b/float ALLOT DOES> F@ ;
: FVARIABLE ( -name- ) \ compile time
( F: -- r ) \ runtime
CREATE b/float ALLOT ;
\ test goodies
: \S CR -1 ABORT" OK, abort at \S point, no more loaded. " ; \ ***
FCLEAR
100 SET-PRECISION \ max precision for testing
CR .( 1/7 = ) 1 S>F 7 S>F F/ F.
CR .( 1/3 = ) 1 S>F 3 S>F F/ F.
CR .( 2/3 = ) 2 S>F 3 S>F F/ F.
CR .( 355/113 = ) 355 S>F 113 S>F F/ F.
: SS fstak 120 DUMP ;
\ DUSMOD.F
\ test in wina64 ok 20170616
: 2>R POSTPONE SWAP POSTPONE >R POSTPONE >R ; IMMEDIATE
: 2R> POSTPONE R> POSTPONE R> POSTPONE SWAP ; IMMEDIATE
: 2R@ POSTPONE 2R> POSTPONE 2DUP POSTPONE 2>R ; IMMEDIATE
: 2ROT 2>R 2SWAP 2R> 2SWAP ;
: PICK 1+ CELLS DSP@ + @ ;
: D2* 2DUP D+ ;
: M+ S>D D+ ;
: DU< ROT 2DUP = IF 2DROP U< EXIT THEN 2SWAP 2DROP SWAP U< ;
: D- DNEGATE D+ ;
\ b/d = bits/double,128 for wina64
: DU/MOD ud1 ud2 -- udrem udquot )
0 0 2ROT
128 ( b/d ) 0
DO 2 PICK OVER 2>R D2* 2SWAP D2*
R> 0< 1 AND M+ 2DUP 7 PICK 7 PICK
DU< 0= R> 0< OR
IF 5 PICK 5 PICK D- 2SWAP 1 M+
ELSE 2SWAP
THEN
LOOP 2ROT 2DROP ;
\ Usage:
\ 170000000000000. 30000000000000. DU/MOD CR D. CR D.
\ (84)STRING.F
\ in wina64 test ok 20170616
1 LOAD
WANT DUMP
WANT ALLOCATE
WANT SEE
: WORD ( c -- addr )
DUP BL = IF DROP NAME ELSE >R \ line933
BEGIN PP@@ R@ = WHILE DROP REPEAT DROP -1 PP +!
R> PARSE THEN HERE 34 BLANK HERE
2DUP C! 1+ SWAP CMOVE \ $!-BD
HERE ;
\ only PP able to be used in file. >IN can not to be used in file.
\ QUERY here can be used in command console so use >IN?
\ ACCEPT ( addr count -- n )
: >IN ( -- )
PP ;
: QUERY ( -- )
TIB @ DUP 80 ACCEPT SET-SRC 0 (>IN) ! ;
: /STRING ( addr1 u1 n -- addr2 u2 )
>R R@ - SWAP R> + SWAP ;
0 CONSTANT FALSE
-1 CONSTANT TRUE
: D>S DROP ;
: DNUMBER ( addr count -- d +f | -f)
0.
2SWAP OVER C@ [CHAR] - = DUP >R
IF 1 /STRING THEN
>NUMBER
SWAP DROP
IF 2DROP R> DROP FALSE
ELSE R>
IF DNEGATE THEN
TRUE
THEN
;
: STRING
CREATE ALLOT ( n -- )
DOES> ( -- addr )
;
256 STRING AAA
256 STRING BBB
VARIABLE CCC
: INPUT$ ( -- addr count )
QUERY 13 WORD COUNT ;
: INPUT# ( -- n )
QUERY BL WORD COUNT DNUMBER
IF D>S ELSE ABORT" Warning! Input unknown?" THEN ;
: TEST
." Enter your name: " INPUT$ CR
." Hello there, " TYPE CR
." Enter a number: " INPUT# CR
." Your number is " . CR
;
: TEST1
." ENTER STRING AAA: " INPUT$ AAA $!
." ENTER STRING BBB: " INPUT$ BBB $!
." ENTER A NUMBER : " INPUT# CCC !
CR AAA $@ TYPE
CR BBB $@ TYPE
CR CCC @ . CR
." ENTER APPENDED STRING : " INPUT$ AAA $+!
CR AAA $@ TYPE
;
\ 4. FILE I/O
\ 100 ALLOCATE DROP CONSTANT DDD
\ AAA $@ DDD SWAP MOVE
\ DDD 40 DUMP
\ This file operation program works in Lina64 under CentOS7
\ Author: Ching Tang Tseng
\ Date : 20160310, Hamilton, New Zealand
\ WANT ALLOCATE
\ -rw0rw0rw0 = 110110110b = 438d : all are R/W enable
438 CONSTANT R/W
VARIABLE FileID
VARIABLE Fptr
VARIABLE Frem
VARIABLE Flen
VARIABLE Fsize 1024000 Fsize !
\ (1)floating Fadr
\ : Fadr PAD 4096 + ;
\ (2)allocate Fadr ???
Fsize @ ALLOCATE DROP CONSTANT Fadr
\ (3)fixed Fadr: 1 MB below EM
\ EM HERE - . --> get 33425420 --> 33 MB free spaces
\ : Fadr EM 1024000 - ;
: SetUpFptrFrem ( -- )
Fadr Fptr !
Flen @ Frem ! ;
: (FILE.) ( -- addr len )
Fadr Flen @ ;
: FileType ( -- )
CR (FILE.) TYPE ;
: FileDump ( -- )
CR (FILE.) DUMP ;
\ Beware! only a R/W attributed file can be manipulated
\ S" Filename.f" GetFile = "Filename.f" GetFile
: GetFile ( addr len -- )
Fadr Fsize @ 0 FILL
R/W OPEN-FILE
IF CR ABORT" OPEN-FILE error?" THEN FileID !
CR ." File ID is : " FileID @ .
Fadr Fsize @ FileID @ READ-FILE
IF CR ABORT" READ-FILE error?" THEN
DUP Flen !
CR . ." Bytes has been read!"
FileID @ CLOSE-FILE
IF CR ABORT" CLOSE-FILE error!" THEN
SetUpFptrFrem ;
\ use PAD area create all blanks
: NewFile ( addr len n -- )
Flen ! PAD Flen @ 32 FILL
R/W CREATE-FILE
IF CR ABORT" CREATE-FILE error!" THEN FileID !
PAD Flen @ FileID @ WRITE-FILE
IF CR ABORT" WRITE-FILE error!" THEN
CR Flen @ . ." Bytes has been written!"
FileID @ CLOSE-FILE
IF CR ABORT" CLOSE-FILE error!" THEN
SetUpFptrFrem ;
\ Beware! Flen must be set, before you WriteFile
: SaveFile ( addr len -- )
R/W CREATE-FILE
IF CR ABORT" CREATE-FILE error!" THEN FileID !
CR ." FileID is: " FileID @ .
Fadr Flen @ FileID @ WRITE-FILE
IF CR ABORT" WRITE-FILE error!" THEN
CR Flen @ . ." Bytes has been written!"
FileID @ CLOSE-FILE
IF CR ABORT" CLOSE-FILE error!" THEN ;
\ for simple testing usage:
\ : SendText>F ( adr n -- )
\ DUP Flen ! Fadr SWAP MOVE ;
\ S" This is a simple test." SendText>F
\ then, use FileType or use FileDump to check
\ Frem, Fptr are to be used for other testing.
\ (85-1)Win32Forth version fvariable ci fvariable c fvariable zi fvariable z : >2? z f@ fdup f* zi f@ fdup f* f+ 4.0e0 f> ; : nextr z f@ fdup f* zi f@ fdup f* f- c f@ f+ ; : nexti z f@ zi f@ f* 2.0e0 f* ci f@ f+ ; : pixel c f! ci f! 0.0e0 z f! 0.0e0 zi f! 150 50 do nextr nexti zi f! z f! >2? if i unloop exit then loop bl ; : left->right -1.5e0 80 0 do fover fover pixel emit 0.026e0 f+ loop fdrop ; : top->bottom -1.0e0 40 0 do left->right cr 0.05e0 f+ loop fdrop ; : main cr top->bottom ; page main \ (85-2)Wina32 ABC Forth512 version fvariable ci fvariable c fvariable zi fvariable z : >2? z f@ fdup f* zi f@ fdup f* f+ 4.0 e 0 f> ; : nextr z f@ fdup f* zi f@ fdup f* f- c f@ f+ ; : nexti z f@ zi f@ f* 2.0 e 0 f* ci f@ f+ ; : pixel c f! ci f! 0.0 e 0 z f! 0.0 e 0 zi f! 150 50 do nextr nexti zi f! z f! >2? if i unloop exit then loop bl ; : left->right -1.5 e 0 79 0 do fover fover pixel emit 0.026 e 0 f+ loop fdrop ; \ 80 ->79 : top->bottom -1.0 e 0 40 0 do left->right cr 0.05 e 0 f+ loop fdrop ; top->bottom \ all ( 0 e 0 ) -> ( 0.0 e 0 ) \ (85-3)Forth64 version fvariable ci fvariable c fvariable zi fvariable z : >2? z f@ fdup f* zi f@ fdup f* f+ 4.0e f> ; : nextr z f@ fdup f* zi f@ fdup f* f- c f@ f+ ; : nexti z f@ zi f@ f* 2.0e f* ci f@ f+ ; : pixel c f! ci f! 0e z f! 0e zi f! 150 50 do nextr nexti zi f! z f! >2? if i unloop exit then loop bl ; : left->right -1.5e 80 0 do fover fover pixel emit 0.026e f+ loop fdrop ; : main ( top->bottom ) cr -1e 40 0 do left->right cr 0.05e f+ loop fdrop ;
沒有留言:
張貼留言