- ABORT
- ABORT"
- ABS
- ACCEPT
- ACTION-OF
- AGAIN
- ALIGN
- ALIGNED
- ALLOT
- AND
- BASE
- BEGIN
- BL
- BUFFER:
- [
- [CHAR]
- [COMPILE]
- [']
- CASE
- C,
- CELL+
- CELLS
- C@
- CHAR
- CHAR+
- CHARS
- COMPILE,
- CONSTANT
- COUNT
- CR
- CREATE
- C!
- :
- :NONAME
- ,
- C"
- DECIMAL
- DEFER
- DEFER@
- DEFER!
- DEPTH
- DO
- DOES>
- DROP
- DUP
- /
- /MOD
- .R
- .(
- ."
- ELSE
- EMIT
- ENDCASE
- ENDOF
- ENVIRONMENT?
- ERASE
- EVALUATE
- EXECUTE
- EXIT
- =
- FALSE
- FILL
- FIND
- FM/MOD
- @
- HERE
- HEX
- HOLD
- HOLDS
- I
- IF
- IMMEDIATE
- INVERT
- IS
- J
- KEY
- LEAVE
- LITERAL
- LOOP
- LSHIFT
- MARKER
- MAX
- MIN
- MOD
- MOVE
- M*
- -
- NEGATE
- NIP
- OF
- OR
- OVER
- 1-
- 1+
- PAD
- PARSE-NAME
- PARSE
- PICK
- POSTPONE
- +
- +LOOP
- +!
- QUIT
- RECURSE
- REFILL
- REPEAT
- RESTORE-INPUT
- R@
- ROLL
- ROT
- RSHIFT
- R>
- SAVE-INPUT
- SIGN
- SM/REM
- SOURCE-ID
- SOURCE
- SPACE
- SPACES
- STATE
- SWAP
- ;
- S\"
- S"
- S>D
- !
- THEN
- TO
- TRUE
- TUCK
- TYPE
- '
- *
- */
- */MOD
- 2DROP
- 2DUP
- 2/
- 2@
- 2OVER
- 2R@
- 2R>
- 2SWAP
- 2!
- 2*
- 2>R
- U.R
- UM/MOD
- UM*
- UNLOOP
- UNTIL
- UNUSED
- U.
- U<
- U>
- VALUE
- VARIABLE
- WHILE
- WITHIN
- WORD
- XOR
- 0=
- 0<
- 0>
- 0<>
- \
- .
- <
- >
- <>
- #>
- <#
- #
- #S
- (
- ?DO
- ?DUP
- >BODY
- >IN
- >NUMBER
- >R
6.1.1561 FM/MOD f-m-slash-mod CORE
Divide d1 by n1, giving the floored quotient n3 and the remainder n2. Input and output stack arguments are signed. An ambiguous condition exists if n1 is zero or if the quotient lies outside the range of a single-cell signed integer.
See:
Rationale:
The committee considered providing two complete sets of explicitly named division operators, and declined to do so on the grounds that this would unduly enlarge and complicate the standard. Instead, implementors may define the normal division words in terms of either FM/MOD or SM/REM providing they document their choice. People wishing to have explicitly named sets of operators are encouraged to do so. FM/MOD may be used, for example, to define:
Testing:
T{ 1 S>D 1 FM/MOD -> 0 1 }T
T{ 2 S>D 1 FM/MOD -> 0 2 }T
T{ -1 S>D 1 FM/MOD -> 0 -1 }T
T{ -2 S>D 1 FM/MOD -> 0 -2 }T
T{ 0 S>D -1 FM/MOD -> 0 0 }T
T{ 1 S>D -1 FM/MOD -> 0 -1 }T
T{ 2 S>D -1 FM/MOD -> 0 -2 }T
T{ -1 S>D -1 FM/MOD -> 0 1 }T
T{ -2 S>D -1 FM/MOD -> 0 2 }T
T{ 2 S>D 2 FM/MOD -> 0 1 }T
T{ -1 S>D -1 FM/MOD -> 0 1 }T
T{ -2 S>D -2 FM/MOD -> 0 1 }T
T{ 7 S>D 3 FM/MOD -> 1 2 }T
T{ 7 S>D -3 FM/MOD -> -2 -3 }T
T{ -7 S>D 3 FM/MOD -> 2 -3 }T
T{ -7 S>D -3 FM/MOD -> -1 2 }T
T{ MAX-INT S>D 1 FM/MOD -> 0 MAX-INT }T
T{ MIN-INT S>D 1 FM/MOD -> 0 MIN-INT }T
T{ MAX-INT S>D MAX-INT FM/MOD -> 0 1 }T
T{ MIN-INT S>D MIN-INT FM/MOD -> 0 1 }T
T{ 1S 1 4 FM/MOD -> 3 MAX-INT }T
T{ 1 MIN-INT M* 1 FM/MOD -> 0 MIN-INT }T
T{ 1 MIN-INT M* MIN-INT FM/MOD -> 0 1 }T
T{ 2 MIN-INT M* 2 FM/MOD -> 0 MIN-INT }T
T{ 2 MIN-INT M* MIN-INT FM/MOD -> 0 2 }T
T{ 1 MAX-INT M* 1 FM/MOD -> 0 MAX-INT }T
T{ 1 MAX-INT M* MAX-INT FM/MOD -> 0 1 }T
T{ 2 MAX-INT M* 2 FM/MOD -> 0 MAX-INT }T
T{ 2 MAX-INT M* MAX-INT FM/MOD -> 0 2 }T
T{ MIN-INT MIN-INT M* MIN-INT FM/MOD -> 0 MIN-INT }T
T{ MIN-INT MAX-INT M* MIN-INT FM/MOD -> 0 MAX-INT }T
T{ MIN-INT MAX-INT M* MAX-INT FM/MOD -> 0 MIN-INT }T
T{ MAX-INT MAX-INT M* MAX-INT FM/MOD -> 0 MAX-INT }T
ContributeContributions
NieDzejkob [50] Implementing FM/MOD with SM/REMSuggested reference implementation2018-01-22 15:32:49
: FM/MOD ( d n -- rem quot )
DUP >R
SM/REM
( if the remainder is not zero and has a different sign than the divisor )
OVER DUP 0<> SWAP 0< R@ 0< XOR AND IF
1- SWAP R> + SWAP
ELSE
RDROP
THEN
;