papierkorb:4th_lesson_5
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| papierkorb:4th_lesson_5 [2025-08-16 19:07] – ↷ Seite von projects:4th_lesson_5 nach papierkorb:4th_lesson_5 verschoben mka | papierkorb:4th_lesson_5 [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| - | === Lesson 5 === | ||
| - | < | ||
| - | \ | ||
| - | \ The Forth Course | ||
| - | \ by Richard E. Haskell | ||
| - | \ Dept. of Computer Science and Engineering | ||
| - | \ Oakland University, Rochester, MI 48309 | ||
| - | comment: | ||
| - | |||
| - | Lesson 5 | ||
| - | |||
| - | NUMBERS | ||
| - | |||
| - | |||
| - | 5.1 DOUBLE NUMBERS | ||
| - | |||
| - | 5.2 DOUBLE COMPARISON OPERATORS | ||
| - | |||
| - | 5.3 MULTIPLICATION AND DIVISION | ||
| - | |||
| - | 5.4 FLOORED DIVISION | ||
| - | |||
| - | 5.5 16-BIT OPERATORS | ||
| - | |||
| - | 5.6 DOUBLE NUMBER MULTIPLICATION | ||
| - | |||
| - | 5.7 EXERCISES | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 5.1 DOUBLE NUMBERS | ||
| - | |||
| - | A double number is a 32-bit integer that is stored as two 16-bit | ||
| - | words on the stack with the HI-word on top of the stack as follows: | ||
| - | |||
| - | ___________ | ||
| - | | HI-word | <---top of stack | ||
| - | |---------| | ||
| - | | LO-word | | ||
| - | |---------| | ||
| - | |||
| - | The stack picture of a double number will be indicated as | ||
| - | |||
| - | ( d -- ) | ||
| - | |||
| - | A double number is entered from the keyboard by including a decimal | ||
| - | point anywhere in the number. | ||
| - | |||
| - | 1234.56 | ||
| - | |||
| - | the integer value 123456 which is equal to the hex value 1E240 | ||
| - | will be stored in the top two words of the stack as follows: | ||
| - | |||
| - | ___________ | ||
| - | | 0 0 0 1 | <---top of stack | ||
| - | |---------| | ||
| - | | E 2 4 0 | | ||
| - | |---------| | ||
| - | |||
| - | The variable DPL will contain the number of places after the decimal | ||
| - | point, 2 in this case. | ||
| - | |||
| - | The Forth word D. can be used to print the value of a double | ||
| - | number on the screen. | ||
| - | the value 123456 will be printed on the screen. | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | The following are some double number words: | ||
| - | |||
| - | D+ ( d d -- dsum ) | ||
| - | Add two double numbers leaving a double sum. | ||
| - | |||
| - | DNEGATE ( d -- d ) | ||
| - | Change the sign of a double number. | ||
| - | |||
| - | S> | ||
| - | Sign extend a single number to a double number. | ||
| - | |||
| - | DABS ( d -- d ) | ||
| - | Take the absolute value of a double number. | ||
| - | |||
| - | D2* ( d -- d*2 ) | ||
| - | 32-bit shift left -- multiply d by 2. | ||
| - | |||
| - | D2/ ( d -- d/2 ) | ||
| - | 32-bit shift right -- divide d by 2. | ||
| - | |||
| - | DMIN ( d1 d2 -- d3 ) | ||
| - | d3 is the lesser of d1 and d2. | ||
| - | |||
| - | DMAX ( d1 d2 -- d3 ) | ||
| - | d3 is the greater of d1 and d2. | ||
| - | |||
| - | |||
| - | D- ( d1 d2 -- d1-d2 ) | ||
| - | Subtract two double numbers leaving a double difference. | ||
| - | |||
| - | Note: the definition of D- is | ||
| - | |||
| - | : D- DNEGATE D+ ; | ||
| - | |||
| - | |||
| - | ? | ||
| - | If n < 0 then DNEGATE d1. | ||
| - | |||
| - | Note: the definition of ?DNEGATE is | ||
| - | |||
| - | : ? | ||
| - | 0< | ||
| - | IF | ||
| - | | ||
| - | THEN ; | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 5.2 DOUBLE COMPARISON OPERATORS | ||
| - | |||
| - | The following are the definitions of comparison operators for | ||
| - | double numbers: | ||
| - | |||
| - | : D0= ( d -- f ) \ flag is TRUE if d = 0 | ||
| - | OR 0= ; | ||
| - | |||
| - | : D= ( d1 d2 -- f ) \ flag is TRUE if d1 = d2 | ||
| - | D- D0= ; | ||
| - | |||
| - | : DU< | ||
| - | ROT SWAP \ ud1L ud2L ud1H ud2H | ||
| - | 2DUP U< \ ud1L ud2L ud1H ud2H f | ||
| - | IF \ ud1L ud2L ud1H ud2H | ||
| - | 2DROP 2DROP TRUE \ f | ||
| - | ELSE | ||
| - | <> | ||
| - | | ||
| - | 2DROP FALSE \ f | ||
| - | ELSE | ||
| - | U< \ f | ||
| - | THEN | ||
| - | THEN ; | ||
| - | |||
| - | : D< ( d1 d2 -- f ) \ flag is TRUE if d1 < d2 | ||
| - | 2 PICK \ d1L d1H d2L d2H d1H | ||
| - | OVER = \ d1L D1H D2L D2H f | ||
| - | IF \ d1L D1H D2L D2H | ||
| - | | ||
| - | ELSE | ||
| - | NIP ROT DROP \ D1H D2H | ||
| - | < | ||
| - | THEN ; | ||
| - | |||
| - | : D> ( di d2 -- f ) \ flag is TRUE if d1 >= d2 | ||
| - | 2SWAP | ||
| - | D< ; | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 5.3 MULTIPLICATION AND DIVISION | ||
| - | |||
| - | The basic multiplication and division operations upon which all | ||
| - | other multiplication and division words are based are | ||
| - | |||
| - | UM* ( un1 un2 -- ud ) | ||
| - | UM* multiplies the unsigned 16-bit integer un1 by the | ||
| - | unsigned 16-bit integer un2 and returns the unsigned | ||
| - | 32-bit product ud. This word uses the 8088/8086 MUL | ||
| - | instruction. | ||
| - | |||
| - | UM/ | ||
| - | UM/MOD divides the unsigned 32-bit integer ud by the 16-bit | ||
| - | unsigned integer un and returns the unsigned quotient uquot | ||
| - | and the unsigned remainder urem. This word uses the | ||
| - | 8088/8086 DIV instruction. | ||
| - | greater than or equal to un then the quotient will not fit | ||
| - | in 16 bits. Under these conditions the 8088/8086 DIV | ||
| - | instruction would produce a " | ||
| - | The Forth word UM/MOD checks for this case and returns a | ||
| - | hex value of FFFF for both the quotient and remainder if | ||
| - | the quotient is too large to fit in 16 bits. | ||
| - | |||
| - | |||
| - | The following F-PC word will multiply two signed 16-bit integers and | ||
| - | leave a 32-bit signed product. | ||
| - | |||
| - | : *D ( n1 n2 -- d ) | ||
| - | 2DUP XOR >R \ save sign of product | ||
| - | ABS SWAP ABS | ||
| - | UM* \ unsigned multiply | ||
| - | R> ?DNEGATE ; \ fix sign | ||
| - | |||
| - | The following F-PC word will divide an unsigned 32-bit integer by | ||
| - | a 16-bit unsigned integer and leave an unsigned 16-bit remainded | ||
| - | and a 32-bit unsigned quotient. | ||
| - | overflow problem of UM/MOD. | ||
| - | |||
| - | : MU/ | ||
| - | >R 0 R@ \ udL udH 0 un | ||
| - | UM/ | ||
| - | R> \ udL remH quotH un | ||
| - | SWAP >R \ udL remH un | ||
| - | UM/ | ||
| - | R> ; \ remL quotL quotH | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 5.4 FLOORED DIVISION | ||
| - | |||
| - | The two signed division words | ||
| - | |||
| - | /MOD ( n1 n2 -- rem quot ) | ||
| - | |||
| - | M/MOD ( d n1 -- rem quot ) | ||
| - | |||
| - | perform floored division. | ||
| - | try to predict what will be displayed on the screen. | ||
| - | |||
| - | 26 7 /MOD . . | ||
| - | |||
| - | -26 7 /MOD . . | ||
| - | |||
| - | 26 -7 /MOD . . | ||
| - | |||
| - | -26 -7 /MOD . . | ||
| - | |||
| - | The results can be summarized as follows: | ||
| - | |||
| - | Dividend | ||
| - | |||
| - | | ||
| - | -26 | ||
| - | | ||
| - | -26 -7 3 -5 | ||
| - | |||
| - | Did you expect these results? | ||
| - | seem strange to you, but they are ok because all we need is the | ||
| - | divisor times the quotient plus the remainder to be equal to | ||
| - | the dividend. | ||
| - | |||
| - | 3 * 7 + 5 = 26 | ||
| - | -4 * 7 + 2 = -26 | ||
| - | -4 * -7 - 2 = 26 | ||
| - | 3 * -7 - 5 = -26 | ||
| - | |||
| - | This is called floored division and is characterized by the sign | ||
| - | of the remainder being the same as the sign of the divisor. | ||
| - | |||
| - | |||
| - | This is not the only way to do division. | ||
| - | IDIV instruction does NOT do floored division. | ||
| - | the sign of the remainder is the same as the sign of the dividend | ||
| - | and the magnitude of the quotient is always the same. | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | To see this define the following code word that uses the IDIV | ||
| - | instruction: | ||
| - | comment; | ||
| - | PREFIX | ||
| - | CODE ?M/MOD | ||
| - | POP BX | ||
| - | POP DX | ||
| - | POP AX | ||
| - | IDIV BX | ||
| - | 2PUSH | ||
| - | END-CODE | ||
| - | |||
| - | comment: | ||
| - | Now type | ||
| - | |||
| - | 26 7 ?M/MOD . . | ||
| - | |||
| - | -26 7 ?M/MOD . . | ||
| - | |||
| - | 26 -7 ?M/MOD . . | ||
| - | |||
| - | -26 -7 ?M/MOD . . | ||
| - | |||
| - | These new results can be summarized as follows: | ||
| - | |||
| - | Dividend | ||
| - | |||
| - | | ||
| - | -26 | ||
| - | | ||
| - | -26 -7 3 -5 | ||
| - | |||
| - | |||
| - | Note that in this case the divisor times the quotient plus the | ||
| - | remainder is still equal to the dividend. | ||
| - | like the looks of this version of division rather than the floored | ||
| - | division, the floored division has the advantage of resolving an | ||
| - | ambiguity around zero. To see this, try the following. | ||
| - | |||
| - | Floored division | ||
| - | | ||
| - | -3 4 /MOD . . -1 1 | ||
| - | 3 -4 /MOD . . -1 -1 | ||
| - | -3 -4 /MOD . . 0 -3 | ||
| - | |||
| - | Non-floored division | ||
| - | | ||
| - | -3 4 ?M/MOD . . 0 -3 | ||
| - | 3 -4 ?M/MOD . . | ||
| - | -3 -4 ?M/MOD . . 0 -3 | ||
| - | |||
| - | Note that the non-floored division can not tell the difference | ||
| - | between 3 4 ?M/MOD and 3 -4 ?M/MOD or between -3 4 ?M/MOD and | ||
| - | -3 -4 ?M/MOD. | ||
| - | |||
| - | Here is how M/MOD is defined: | ||
| - | |||
| - | : M/MOD ( d n -- rem quot ) | ||
| - | ?DUP \ return d if n = 0 | ||
| - | IF \ dL dH n | ||
| - | DUP >R \ save n | ||
| - | 2DUP XOR >R \ save sign | ||
| - | > | ||
| - | DABS R@ ABS \ |dL dH| |n| | ||
| - | | ||
| - | SWAP R> \ uquot urem n | ||
| - | ? | ||
| - | SWAP R> \ rem uquot xor | ||
| - | 0< | ||
| - | | ||
| - | NEGATE | ||
| - | OVER \ rem quot rem | ||
| - | IF \ rem quot | ||
| - | | ||
| - | | ||
| - | ROT - \ quot floor.rem = n - rem | ||
| - | | ||
| - | THEN | ||
| - | THEN | ||
| - | R> DROP | ||
| - | THEN ; | ||
| - | |||
| - | |||
| - | /MOD could then defined as follows: | ||
| - | |||
| - | : /MOD ( n1 n2 -- rem quot ) | ||
| - | >R S>D R> | ||
| - | M/MOD ; | ||
| - | |||
| - | F-PC actually defines /MOD as a code word which uses IDIV | ||
| - | followed by a flooring of the remainder and quotient. | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 5.5 16-BIT OPERATORS | ||
| - | |||
| - | The following is the way that the arithmetic operators that operate | ||
| - | on 16-bit numbers and leave 16-bit results could be defined. | ||
| - | Actually, F-PC defines many of these as equivalent code words | ||
| - | for speed. | ||
| - | |||
| - | : * ( n1 n2 -- n ) \ signed multiply | ||
| - | UM* DROP ; | ||
| - | |||
| - | Although this may seem strange, it is true that | ||
| - | if you simply throw away the high word of an | ||
| - | unsigned 32-bit product you will get the correct | ||
| - | 16-bit signed answer. | ||
| - | must be in the range -32768 to +32767. | ||
| - | |||
| - | |||
| - | : / ( n1 n2 -- n ) \ signed division | ||
| - | /MOD NIP ; | ||
| - | |||
| - | |||
| - | : MOD ( n1 n2 -- rem ) | ||
| - | /MOD DROP ; | ||
| - | |||
| - | |||
| - | : */MOD ( n1 n2 n3 -- rem n1*n2/n3 ) | ||
| - | >R \ n1 n2 | ||
| - | *D \ n1*n2 (32-bit product) | ||
| - | R> \ n1*n2 n3 | ||
| - | M/MOD ; \ rem quot | ||
| - | |||
| - | Note that the quotient is equal to n1*n2/n3 | ||
| - | where the intermediate product n1*n2 retains | ||
| - | 32 bits. | ||
| - | |||
| - | |||
| - | : */ ( n1 n2 n3 -- n1*n2/n3 ) | ||
| - | */MOD NIP ; | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | Suppose you would like to compute n1*n2/n3 rounded to the nearest | ||
| - | integer. | ||
| - | |||
| - | n1*n2/n3 = Q + R/n3 | ||
| - | |||
| - | where Q is the quotient and R is the remainder. | ||
| - | 1/2 to the fractional part of the answer. | ||
| - | |||
| - | n1*n2/n3 = Q + R/n3 + 1/2 | ||
| - | |||
| - | which we can write as | ||
| - | |||
| - | n1*n2/n3 = Q + (2*R + n3)/2*n3 | ||
| - | |||
| - | We can then define */R to compute n1*n2/n3 rounded as follows: | ||
| - | comment; | ||
| - | |||
| - | : */R ( n1 n2 n3 -- n1*n2/n3 rounded ) | ||
| - | DUP 2SWAP \ n3 n3 n1 n2 | ||
| - | ROT \ n3 n1 n2 n3 | ||
| - | */MOD \ n3 R Q | ||
| - | -ROT 2* \ Q n3 2*R | ||
| - | OVER + \ Q n3 2*R+n3 | ||
| - | SWAP 2* \ Q 2*R+n3 2*n3 | ||
| - | / + ; | ||
| - | |||
| - | comment: | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | 5.6 DOUBLE NUMBER MULTIPLICATION | ||
| - | |||
| - | Sometimes it is necessary to multiply a double number (32-bits) | ||
| - | by a single number (16-bits) and obtain a double number result. | ||
| - | Of course, in general, if you multiply a 32-bit number by a | ||
| - | 16-bit number you could get as much as a 48-bit product. | ||
| - | in many cases you will know that the result can't exceed 32-bits, | ||
| - | even though it will be greater than 16-bits. | ||
| - | |||
| - | Suppose that A, B, C, D, E, F and G are 16-bit numbers. | ||
| - | can represent the multiplication of the 32-bit number A:B by the | ||
| - | 16 bit number C as follows: | ||
| - | |||
| - | A B | ||
| - | ----- ----- | ||
| - | C | ||
| - | | ||
| - | | ||
| - | |||
| - | D E | ||
| - | ----- ----- | ||
| - | | ||
| - | | ||
| - | | ||
| - | |||
| - | | ||
| - | ----- ----- | ||
| - | |||
| - | In this diagram, multiplying B times C gives the 32-bit result D:E. | ||
| - | Multiplying A times C gives the 32-bit result G:F. Adding these | ||
| - | two partial products, shifted by 16-bits as shown, will produce | ||
| - | the complete 48-bit product. | ||
| - | and limit the result to 32 bits. The low word of this product | ||
| - | will be pL = E and the high word will be pH = D + F. Therefore, | ||
| - | we can define the following word to do this multiplication. | ||
| - | comment; | ||
| - | |||
| - | : DUM* ( ud un -- ud ) | ||
| - | DUP \ B A C C | ||
| - | ROT \ B C C A | ||
| - | * \ B C F | ||
| - | -ROT \ F B C | ||
| - | UM* \ F E D | ||
| - | ROT \ E D F | ||
| - | + ; \ pL pH | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | comment: | ||
| - | 5.7 EXERCISES | ||
| - | |||
| - | | ||
| - | ball bearings. | ||
| - | bearings in terms of pixel counts. | ||
| - | (corresponding to a diameter) is 256. The system is adjusted | ||
| - | so that 100 pixels corresponds to 1 cm. The ball bearings | ||
| - | measured with this device range in diameter from 0.25 to 2.5 cm. | ||
| - | |||
| - | Write a Forth word called VOLUME that will expect a diameter in | ||
| - | pixel counts on the stack and will leave the volume of the ball | ||
| - | bearing, rounded to the nearest cubic mm, on the stack. | ||
| - | |||
| - | Note: The volume of a sphere is (4/ | ||
| - | | ||
| - | by 355/113. | ||
| - | |||
| - | Test your program with the following values of the diameter: | ||
| - | |||
| - | 25 50 100 | ||
| - | |||
| - | comment; | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | </ | ||
papierkorb/4th_lesson_5.1755364027.txt.gz · Zuletzt geändert: 2025-08-16 19:07 von mka