home *** CD-ROM | disk | FTP | other *** search
- \ Problem 4.25 04/16/90 16:57:15.07
-
-
- : #IN ( -- n )
- QUERY INTERPRET ;
-
- : EASY-BITS ( drem1 partial.root1 count -- drem2 partial.root2 )
- 0 DO >R D2* D2*
- R@ - DUP 0<
- IF R@ + R> 2* 1-
- ELSE R> 2* 3 +
- THEN LOOP ;
-
- : 2'S-BIT ( drem2 proot2 -- drem3 proot3 ) \ get penultimate bit
- >R D2* DUP 0<
- IF D2* R@ - R> 1+
- ELSE D2* R@ 2DUP U<
- IF DROP R> 1-
- ELSE - R> 1+
- THEN THEN ;
-
- \ Get the last bit.
- : 1'S-BIT ( drem3 proot3 -- fullroot ) \ remainder lost
- >R DUP 0<
- IF 2DROP R> 1+
- ELSE D2* 32768 R@ DU< 0= R> THEN ;
-
- \ 32-bit unsigned radicand to 16-bit unsigned square root
- : SQRT ( ud -- un ) \ un is the 16-bit square root of 32-bit ud.
- 0 1 8 EASY-BITS ROT DROP 6 EASY-BITS
- 2'S-BIT 1'S-BIT SWAP DROP ; \ SWAP DROP added to leave 16-bits
-
- \ Display 16-bit number with two decimal places.
- \ Don't worry about how this works... It will be explained in a
- \ later tutorial lesson.
- : I.XX ( 100*n -- )
- 0 <# # # ASCII . HOLD #S #>
- TYPE SPACE ;
-
- \ Display square root on n to 2 decimal places.
- \ Number is scaled by 10000 first forming a 32-bit product so
- \ that no significance is lost.
- : .SQRT ( n -- )
- 10000 UM* SQRT I.XX ;
-
- \ Polygon Area & Perimeter
- CREATE X 102 ALLOT \ Array for x coordinates
- CREATE Y 102 ALLOT \ Array for y coordinates
- VARIABLE #POINTS \ Number of points in polygon
- VARIABLE AREA \ Sum of the x(i)y(i-1) - x(i)y(i+1)
- VARIABLE PERIMETER \ Sum of [{x(i)-x(i-1)}^2+{y(i)-y(i-1)}]^.5
-
- \ Fetch ith x component.
- : X@ ( i x{i} ) 2* X + @ ;
- \ Fetch ith y component.
- : Y@ ( i y{i} ) 2* Y + @ ;
- \ Store ith x component.
- : X! ( x i -- ) 2* X + ! ;
- \ Store ith y component.
- : Y! ( y i -- ) 2* Y + ! ;
-
-
- \ Move to the next tab stop.
- : TAB ( -- -- )
- BEGIN #OUT @ 8 MOD
- IF SPACE ELSE EXIT THEN
- AGAIN ;
-
- \ Get number from keyboard.
- : GET# ( -- n )
- ASCII > EMIT SPACE #IN ;
-
- \ Prompt and fetch number of data points.
- : GET_#POINTS ( -- )
- BEGIN
- CR ." Enter number of data points. "
- GET# DUP 3 <
- WHILE CR ." You need at least 3 data points!"
- REPEAT 50 MIN #POINTS ! ;
-
-
- \ Prompt and fetch all data points.
- : GET_DATA ( -- )
- CR CR ." Point " TAB ." X" TAB ." Y"
- #POINTS @ 1+ 1
- DO CR I 3 .R TAB GET# I X!
- TAB GET# I Y! LOOP
- #POINTS @ DUP X@ 0 X! Y@ 0 Y! ;
-
- \ Sum data points.
- : FIND_AREA ( -- )
- 0 AREA !
- #POINTS @ 1+ 1 ( n+1 so we loop n times )
- DO I X@ I 1- Y@ * ( X{i}*Y{i-1} )
- I 1- X@ I Y@ * ( X{i-1}*Y{i} )
- - AREA +!
- LOOP ;
-
- \ Calculate the distance between (x1,y1) and (x2,y2)
- : DIST ( x2 y2 x1 y1 -- 100*d )
- ROT - DUP * \ x2 x1 (y1-y2)^2
- -ROT - DUP * \ (y1-y2)^2 (x2-x1)^2
- + 10000 UM* SQRT ; \ 100*d
-
- \ Find the perimeter of the polygon saving result in the
- \ Variable PERIMETER
- : FIND_PERIMETER ( -- )
- 0 PERIMETER !
- #POINTS @ 1+ 1
- DO I X@ I Y@
- I 1- X@ I 1- Y@
- DIST PERIMETER +!
- LOOP ;
-
- \ Display computed area.
- : PUT_AREA ( -- )
- AREA @ 2 /MOD
- CR ." AREA = " 6 .R ASCII . EMIT
- IF ASCII 5 EMIT ELSE ASCII 0 EMIT THEN SPACE ;
-
- \ Display computed perimeter.
- : PUT_PERIMETER ( -- )
- CR ." PERIMETER = "
- PERIMETER @ I.XX ;
-
- \ Compute area of polygon.
- : POLY ( -- )
- GET_#POINTS GET_DATA
- FIND_AREA FIND_PERIMETER
- PUT_AREA PUT_PERIMETER ;
-
-
-
-