The UD/MOD base primitive approach was what I first considered and implemented. I came across
this in VolksForth, which builds UD/MOD on top of UM/MOD , instead of the other way around. This is cool because, in my opinion, 32/32-bit division is seldom invoked and will be even more rare in my own application code, so I don't want to punish the user on every occurrence of division by crunching the whole 32-bits using UD/MOD as the basic primitive. Also UD/MOD isn't part of the Fig, Forth-79, Forth-83 or ANS standards, while UM/MOD is in the required wordset for Forth-83, aka U/MOD in Forth-79.
Code: Select all
: ud/mod ( ud1 u2 -- urem udquot )
>r 0 r@ um/mod r> swap >r um/mod r> ;
For general purpose division, I'm thinktanking an approach to UM/MOD that shifts the divisor left until it's >= the dividend, then do the usual trial-subtract from the dividend and right-shift the divisor thing until the divisor is back to its original alignment. Counting the divisor shifts and counting them back down. If something like this already exists, or anybody here is bored, or if this is a really dumb idea, I'm all ears. The reason for this is that numerator and denominator values are small values most of the time, and operating on all those leading zero bits is a waste of CPU. If somewhat bigger, more complicated code can avoid iterating through trial-subtract for each bit alignment every time through, I'd consider replacing the smaller, simpler UM/MOD code.
Most commonly I'll be using 40/MOD which is a specialty division by the constant 40, to index into the 40-column wide screen on a PET or C=64, and for unpacking text encoded in the
RADIX-50 scheme. Pictured numeric output e.g. <# #S #> also requires division, so I'll overload the 40/MOD primitive a bit to work with BASE @ as the divisor for that purpose. All the other standard general-purpose division and modulo words, including UD/MOD will be built on top of UM/MOD. I'm going to use floored division (remainders are always positive) as per the Forth-83 standard.