Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Conklin E.K.Forth programmer's handbook.2000.pdf
Скачиваний:
321
Добавлен:
23.08.2013
Размер:
2.04 Mб
Скачать

Forth Programmer’s Handbook

2.2 ARITHMETIC AND LOGICAL OPERATIONS

Forth offers a comprehensive set of commands for performing arithmetic and logical functions. The functions in a standard system are optimized for integer arithmetic, because not all processors have hardware floating-point capability and software floating point is too slow for most real-time applications. All Forth systems provide words to perform fast, precise, scaled-integer computations; many provide fixed-point fraction computations, as well. On systems with hardware floating-point capability, many implementations include an optional, complete set of floating-point operations, including an assembler. See Section 3.8 in this manual and the product documentation for these systems for details.

2.2.1 Arithmetic and Shift Operators

In order to achieve maximum performance, each version of Forth implements most arithmetic primitives to use the internal behavior of that particular processor’s hardware multiply and divide instructions. Therefore, to find out at the bit level what these primitives do, you should consult either the manufacturer’s hardware description or the implementation’s detailed description of these functions.

In particular, signed integer division where only one operand (either dividend or divisor) is negative and there is a remainder may produce different, but equally valid, results on different implementations. The two possibilities are floored and symmetric division. In floored division, the remainder carries the sign of the divisor and the quotient is rounded to its arithmetic floor (towards negative infinity). In symmetric division, the remainder carries the sign of the dividend and the quotient is rounded towards zero, or truncated. For example, dividing -10 by 7 can give a quotient of -2 and remainder of 4 (floored), or a quotient of -1 and remainder of -3 (symmetric).

Most hardware multiply and divide instructions are symmetric, so floored division operations are likely to be slower. However, some applications (such as graphics) require floored division in order to get a continuous function through zero. Consult your system’s documentation to learn its behavior.

The following general guidelines may help you use these arithmetic operators:

Forth Fundamentals 39

Forth Programmer’s Handbook

!The order of arguments to order-dependent operators (e.g., - and /) is such that, if the operator were moved to an infix position, it would algebraically describe the result. Some examples:

Forth Algebraic

a b -

a - b

a

b

/

a

/

b

a

b

c */

a

*

b / c

!All arithmetic words starting with the letter U are unsigned; others are normally signed. The exception to this rule is that, on most systems, M*/ requires a positive divisor.

!When executing operations involving address calculations, use the words CELL+, CELLS, CHAR+, and CHARS as appropriate to convert logical values to bytes, rather than to absolute numbers. For example, to increment an address by three cells on a 32-bit system, use 3 CELLS +, not 12 +; this makes the code portable to systems that may have different cell widths.

These operators perform arithmetic and logical functions on numbers that are on the stack. In general, the operands are removed (popped) from the stack and the results are left on the stack.

Glossary Single-Precision Operations

 

*

 

( n1 n2 — n3 )

Core

 

Multiply n1

by n2 leaving the product n3. “star”

*/

 

( n1

n2

n3 — n4 )

Core

 

Multiply n1

by n2, producing an intermediate double-cell result d. Divide d by

 

n3, giving the single-cell quotient n4. “star-slash”

*/MOD

 

( n1

n2

n3 — n4 n5 )

Core

 

Multiply n1

by n2, producing intermediate double-cell result d. Divide d by n3,

 

giving single-cell remainder n4 and single-cell quotient n5. “star-slash-mod”

+

 

( n1

n2

— n3 )

Core

 

Add n1 to n2, leaving the sum n3. “plus”

 

-

 

( n1

n2

— n3 )

Core

 

Subtract n2 from n1, leaving the difference n3.

“minus”

40 Forth Fundamentals

 

Forth Programmer’s Handbook

/

( n1 n2 — n3 )

Core

 

Divide n1 by n2, leaving the quotient n3. See the discussion at the beginning of

 

this section about floored and symmetric division. “slash”

 

/MOD

( n1 n2 — n3 n4 )

Core

 

Divide n1 by n2, leaving the remainder n3 and the quotient n4. “slash-mod”

1+

( n1 — n2 )

Core

 

Add one to n1, leaving n2. “one-plus”

 

1-

( n1 — n2 )

Core

 

Subtract one from n1, leaving n2. “one-minus”

 

2+

( n1 — n2 )

common usage

 

Add two to n1, leaving n2. “two-plus”

 

2-

( n1 — n2 )

common usage

 

Subtract two from n1, leaving n2. “two-minus”

 

2*

( x1 — x2 )

Core

 

Return x2, the result of shifting x1 one bit toward the most-significant bit, filling

 

the least-significant bit with zero (same as 1 LSHIFT). “two-star”

2/

( x1 — x2 )

Core

 

Return x2, the result of shifting x1 one bit towards the least-significant bit, leav-

 

ing the most-significant bit unchanged. “two-slash”

 

CELL+

( a-addr1 — a-addr2 )

Core

 

Add the size in bytes of a cell to a-addr1, giving a-addr2. Equivalent to 2+ on a

 

16-bit system and to 4 + on a 32-bit system. “cell-plus”

 

CELLS

( n1 — n2 )

Core

 

Return n2, the size in bytes of n1 cells.

 

CHAR+

( c-addr1 — c-addr2 )

Core

 

Add the size in bytes of a character to c-addr1, giving c-addr2. “care-plus”

CHARS

( n1 — n2 )

Core

 

Return n2, the size in bytes of n1 characters. On many systems, this word is a

 

no-op. “cares”

 

Forth Fundamentals 41

Forth Programmer’s Handbook

LSHIFT

( x1 u — x2 )

Core

 

Perform a logical left shift of u places on x1, giving x2. Fill the vacated least-

 

significant bits with zeroes. “L-shift”

 

MOD

( n1 n2 — n3 )

Core

 

Divide n1 by n2, giving the remainder n3.

 

RSHIFT

( x1 u — x2 )

Core

 

Perform a logical right shift of u places on x1, giving x2. Fill the vacated most-

 

significant bits with zeroes. “R-shift”

 

 

Double-precision Operations

 

D+

( d1 d2 — d3 )

Double

 

Add d1 to d2, leaving the sum d3. “D-plus”

 

D-

( d1 d2 — d3 )

Double

 

Subtract d2 from d1, leaving the difference d3.

“D-minus”

D2*

( xd1 — xd2 )

Double

 

Return xd2, the result of shifting xd1 one bit toward the most-significant bit and

 

filling the least-significant bit with zero. “D-two-star”

D2/

( xd1 — xd2 )

Double

 

Return xd2, the result of shifting xd1 one bit towards the least-significant bit

 

and leaving the most-significant bit unchanged. “D-two-slash”

 

Mixed-precision Operations

 

D>S

( d — n )

Double

 

Convert double-precision number d to its single-precision equivalent n. Results

 

are undefined if d is outside the range of a signed single-cell number. “D-to-S”

FM/MOD

( d n1 — n2 n3 )

Core

 

Divide d by n1, using floored division, giving quotient n3 and remainder n2. All

 

arguments are signed. This word and SM/REM will produce different results on

the same data when exactly one argument is negative and there is a remainder.

“F-M-slash-mod”

42 Forth Fundamentals

Forth Programmer’s Handbook

M*

( n1 n2 — d )

Core

 

Multiply n1 by n2, leaving the double-precision result d.

“M-star”

M*/

( d1 n1 +n2 — d2 )

Double

Multiply d1 by n1, producing a triple-cell intermediate result t. Divide t by the positive number n2 giving the double-cell quotient d2. If double-precision multiplication or division only is needed, this word may be used with either n1 or

n2 set equal to 1.

“M-star-slash”

 

M+

( d1 n — d2 )

Double

Add n to d1, leaving the sum d2. “M-plus”

 

M-

( d1 n — d2 )

common usage

Subtract n from d1, leaving the difference d2.

“M-minus”

M/

( d n1 — n2 )

common usage

Divide d by n1, leaving the single-precision quotient n2. This word does not

perform an overflow check. “M-slash”

 

S>D

( n — d )

Core

Convert a single-precision number n to its double-precision equivalent d with

the same numerical value. “S-to-D”

 

SM/REM

( d n1 — n2 n3 )

Core

Divide d by n1, using symmetric division, giving quotient n3 and remainder n2. All arguments are signed. This word and FM/MOD will produce different results on the same data when exactly one argument is negative and there is a remainder. “S-M-slash-rem”

T*

( d n — t )

common usage

 

Multiply d by n, yielding a triple-precision result t.

Used in M*/. “T-star”

T/

( t +n — d )

common usage

 

Divide a triple-precision number t by the positive number +n, leaving a double-

 

precision result d. Used in M*/. “T-slash”

 

UM/MOD

( ud u1 — u2 u3 )

Core

Divide ud by u1, leaving remainder u2 and quotient u3. This operation is called UM/MOD because it assumes the arguments are unsigned, and it produces unsigned results. Compare with SM/REM and FM/MOD. “U-M-slash-mod”

Forth Fundamentals 43

Соседние файлы в предмете Электротехника