6.1.2214 SM/REM s-m-slash-rem CORE

( d1 n1 -- n2 n3 )

Divide d1 by n1, giving the symmetric 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:

See the previous discussion of division under FM/MOD. SM/REM is the symmetric-division primitive, which allows programs to define the following symmetric-division operators:

: /-REM ( n1 n2 -- n3 n4 ) >R S>D R> SM/REM ;

: /- ( n1 n2 -- n3 ) /-REM SWAP DROP ;

: -REM ( n1 n2 -- n3 ) /-REM DROP ;

: */-REM ( n1 n2 n3 -- n4 n5 ) >R M* R> SM/REM ;

: */- ( n1 n2 n3 -- n4 ) */-REM SWAP DROP ;

Testing:

T{       0 S>D              1 SM/REM ->  0       0 }T
T{       1 S>D              1 SM/REM ->  0       1 }T
T{       2 S>D              1 SM/REM ->  0       2 }T
T{      -1 S>D              1 SM/REM ->  0      -1 }T
T{      -2 S>D              1 SM/REM ->  0      -2 }T
T{       0 S>D             -1 SM/REM ->  0       0 }T
T{       1 S>D             -1 SM/REM ->  0      -1 }T
T{       2 S>D             -1 SM/REM ->  0      -2 }T
T{      -1 S>D             -1 SM/REM ->  0       1 }T
T{      -2 S>D             -1 SM/REM ->  0       2 }T
T{       2 S>D              2 SM/REM ->  0       1 }T
T{      -1 S>D             -1 SM/REM ->  0       1 }T
T{      -2 S>D             -2 SM/REM ->  0       1 }T
T{       7 S>D              3 SM/REM ->  1       2 }T
T{       7 S>D             -3 SM/REM ->  1      -2 }T
T{      -7 S>D              3 SM/REM ->  1      -2 }T
T{      -7 S>D             -3 SM/REM -> -1       2 }T
T{ MAX-INT S>D              1 SM/REM ->  0 MAX-INT }T
T{ MIN-INT S>D              1 SM/REM ->  0 MIN-INT }T
T{ MAX-INT S>D        MAX-INT SM/REM ->  0       1 }T
T{ MIN-INT S>D        MIN-INT SM/REM ->  0       1 }T
T{      1S 1                4 SM/REM ->  3 MAX-INT }T
T{       2 MIN-INT M*       2 SM/REM ->  0 MIN-INT }T
T{       2 MIN-INT M* MIN-INT SM/REM ->  0       2 }T
T{       2 MAX-INT M*       2 SM/REM ->  0 MAX-INT }T
T{       2 MAX-INT M* MAX-INT SM/REM ->  0       2 }T
T{ MIN-INT MIN-INT M* MIN-INT SM/REM ->  0 MIN-INT }T
T{ MIN-INT MAX-INT M* MIN-INT SM/REM ->  0 MAX-INT }T
T{ MIN-INT MAX-INT M* MAX-INT SM/REM ->  0 MIN-INT }T
T{ MAX-INT MAX-INT M* MAX-INT SM/REM ->  0 MAX-INT }T

ContributeContributions

MarekBrundaavatar of MarekBrunda [138] There is error in testingComment2020-06-21 09:31:29

This line: T{ -7 S>D 3 SM/REM -> 1 -2 }T

should be: T{ -7 S>D 3 SM/REM -> -1 -2 }T

AntonErtlavatar of AntonErtl

confirmed

StephenPelcavatar of StephenPelc

Passed to editor

Accepted

EricDennisonavatar of EricDennison

Should the original (presumably incorrect) version of this test still appear here and at F.6.1.2214 SM/REM ?

ruvavatar of ruv

This web-page shows the contents of the sections 6.1.2214 and F.6.1.2214 in Forth-2012 (pdf) (see also Intro). If this content is changed, it will no longer reflect Forth-2012. I think that only a web-page with erratum (or a special comment in each web-page) can be added to Forth-2012 and here.

See also the issue: Support several versions of the standard in parallel.

Reply New Version