I'm leaning toward PETTIL having these, with "floored division" throughout. That way I can legitimately include the word FORTH-83 in my dictionary. Also I'd like to have code for division/modulo and multiplication exactly once, in accordance with Ruby's DRY principle.
/ * */ */MOD /MOD MOD UM* UM/MOD M* M*/
Having grabbed Garth's code for division from http://6502.org/source/integers/ummodfix/ummodfix.htm and the multiplication from http://6502.org/source/integers/32muldiv.htm , the unsigned part of this is working. I'll implement the signed stuff by subroutine calls to the unsigned math, XORing the sign bits and a bit of branching.
Dilemma 1: Garth's code returns $FFFFFFFF in the event of an error (quotient overflow or division by zero attempt). This could be confused with the results of " -8. 7 sm/rem " which in gforth returns " -1 -1 ". I was thinking about having the rule "remainders are always positive" and then I could test the sign of the remainder to determine if it was an error or not, but something about violating all three standards documents bothers me.
On a semi-related note, I am thinking about implementing a complete suite of floating point, based on the simple expedient of calling the PET ROM math routines and passing things around as 24-bit values on the stack.
What say you, geniuses? Any thoughts?
Everything below this point was extracted verbatim from the various standards documents:
Forth-79 required words
/ * */ */MOD /MOD MOD U* U/
Forth-83 required words
/ * */ */MOD /MOD MOD UM* UM/MOD
DPANS adds these to Forth-83
FM/MOD M* M*/ SM/REM
Integer division
Division produces a quotient q and a remainder r by dividing operand a by operand b. Division operations return q, r, or both. The identity b*q + r = a shall hold for all a and b. When unsigned integers are divided and the remainder is not zero, q is the largest integer less than the true quotient.
The Forth-79 Standard specifies that the signed division operators (/, /MOD, MOD, */MOD, and */) round non-integer quotients towards zero (symmetric division). Forth-83 changed the semantics of these operators to round towards negative infinity (floored division). Some in the Forth community have declined to convert systems and applications from the Forth-79 to the Forth-83 divide. To resolve this issue, an ANS Forth system is permitted to supply either floored or symmetric operators. In addition, ANS Forth systems must provide a floored division primitive (FM/MOD), a symmetric division primitive (SM/REM), and a mixed precision multiplication operator (M*).
When signed integers are divided, the remainder is not zero, and a and b have the same sign, q is the largest integer less than the true quotient. If only one operand is negative, whether q is rounded toward negative infinity (floored division) or rounded towards zero (symmetric division) is implementation defined.
In cases where the operands differ in sign and the rounding direction matters, a program shall either include code generating the desired form of division, not relying on the implementation-defined default result, or have an environmental dependency on the desired rounding direction.
Floored division is integer division in which the remainder carries the sign of the divisor or is zero, and the quotient is rounded to its arithmetic floor.
Code: Select all
Floored Division Example
Dividend Divisor Remainder Quotient
-------- ------- --------- --------
10 7 3 1
-10 7 4 -2
10 -7 -4 -2
-10 -7 -3 1Code: Select all
Symmetric Division Example
Dividend Divisor Remainder Quotient
-------- ------- --------- --------
10 7 3 1
-10 7 -3 -1
10 -7 3 -1
-10 -7 -3 1