minforth <
minf...@arcor.de> writes:
>Nice overview by 'Skanthak'. But I am astonished at those complications he =
>is
>demonstrating there, and at those required code lengths.
>
>I think Forth can do better. FWIW what I am using so far without trouble:
>
>\ Non standard:
>\ Primitive: _MU/MOD \ ( ud v - r udq ) mixed unsigned division (gforth: U=
>D/MOD)
>\ : PLUCK 2 pick ;
>
>: D/REM \ ( du dv -- drem dquot ) MF double number signed symmetric divisi=
>on
> pluck >r pluck over xor >r \ remember signs
> dabs 2swap dabs 2swap dup IF=20
>C mfUCell ul=3Dmffth, uh=3Dmfthd, vl=3Dmfsec, vh=3Dmftos; // copy Forth=
> stack to C unsigned variables
>C mfUCell q=3D0, m=3D1;=20
>C if ((uh=3D=3Dvh)&&(ul=3D=3Dvl)) uh=3Dul=3D0, q=3D1;
>C else { // shift and subtract
>C while(vh=3D=3Duh?vl<=3Dul:vh<=3Duh)
>C vh=3D(vh<<1)|(vl>>63), vl<<=3D1, m<<=3D1;
>C while(m>1) {
>C vl=3D(vl>>1)|(vh<<63), vh>>=3D1, m>>=3D1;
>C if (uh=3D=3Dvh?ul>=3Dvl:uh>=3Dvh) {
>C uh-=3Dvh+(vl>ul), ul-=3Dvl, q|=3Dm; } } }=20
>C mffth=3Dul, mfthd=3Duh, mfsec=3Dq, mftos=3D0;
> ELSE drop _mu/mod 0 -rot THEN
> r> 0< IF dnegate THEN \ apply signs
> r> 0< IF 2swap dnegate 2swap THEN ;
>
>Don't bother about this seemingly wild mix of Forth and C code. All I want =
>to show here
>is how compact it can be.
Except that it does not solve the problem "none albert" asked for:
Implementing double/single->single with single/single->single, faster
than shift-and-subtract.
What you provide is an implementation of double/double->double that
uses shift-and-subtract in the general case and calls a pre-existing
implementation of double/single->double in Forth, without showing how
that is implemented. In Gforth the latter is implemented as
: ud/mod ( ud1 u2 -- urem udquot ) \ gforth
\G divide unsigned double @i{ud1} by @i{u2}, resulting in a unsigned double
\G quotient @i{udquot} and a single remainder @i{urem}.
over 0= if nip u/mod 0 exit then
dup >r u/mod r> swap >r um/mod r> ;
And this implementation uses UM/MOD, which is the word that "none
albert" has asked about.
So we have an onion of division words, starting from the core:
u/mod (called by) um/mod (called by) ud/mod (called by) d/rem
The first part can be skipped if the architecture directly supports
UM/MOD, or if it does not have division instructions.