Modular arithmetic: Difference between revisions

Content added Content deleted
m (J)
(Adding the Forth solution)
Line 557: Line 557:
MI{ 3 7 } 50 ^ = MI{ 2 7 }
MI{ 3 7 } 50 ^ = MI{ 2 7 }
</pre>
</pre>
=={{header|Forth}}
\ We would normally define operators that have a suffix `m' in order
\ not be confused: +m -m *m /m **m
\ Also useful is %:m reduce a number modulo.

\ Words that may be not be present in the kernel.
\ This example loads them in ciforth.
WANT ALIAS VOCABULARY

VARIABLE _m ( Modulo number)
\ Set the modulus to m .
: set-modulus _m ! ;

\ For A B return C GCD where C*A+x*B=GCD
: XGCD 1 0 2SWAP BEGIN OVER /MOD OVER WHILE >R SWAP
2SWAP OVER R> * - SWAP 2SWAP REPEAT 2DROP NIP ;
\ Suffix n : normalized number.
: _norm_-m DUP 0< _m @ AND + ; ( x -- xn ) \ -m<xn<+m
: +m + _m @ - _norm_-m ; ( an bn -- sumn )
: -m - _norm_-m ; ( an bn -- diffn)
: *m M* _m @ SM/REM DROP ; ( an bn -- prodn)
: /m _m @ XGCD DROP _norm_-m *m ; ( a b -- quotn)
: %:m S>D _m @ SM/REM DROP _norm_-m ; ( a -- an)

\ Both steps: For A B and C: return A B en C. Invariant A*B^C.
: _reduce_1- 1- >R >R R@ *m R> R> ;
: _reduce_2/ 2/ >R DUP *m R> ;
: **m 1 ROT ROT BEGIN DUP 1 AND IF _reduce_1- THEN
_reduce_2/ DUP 0= UNTIL 2DROP ; ( a b -- apowbn )
\ The solution is
13 set-modulus

10 DUP 100 **m +m 1 +m . CR

\ In order to comply with the problem we can generate a separate namespace
\ and import the above definitions.

VOCABULARY MODULO
ALSO MODULO DEFINITIONS
' set-modulus ALIAS set-modulus
' +m ALIAS +
' -m ALIAS -
' *m ALIAS *
' /m ALIAS /
' **m ALIAS **

\ now the calculation becomes
13 set-modulus
10 DUP 100 ** + 1 + . CR



=={{header|Go}}==
=={{header|Go}}==