( Multiply two unsigned integers )
-( a b -- b*a )
+( a b -- a*b )
mul_uu:
#8 0i8 ~ >r >r >r #8 0i8 ( acc ) ( ctr b a )
.loop:
drop drop drop ;
+( Compute division with remainder of two unsigned integers )
+( a b -- a%b a/b )
+divmod_uu:
+ #8 0i8 ~ >r >r >r #8 0i8 ( rem ) ( ctr b a )
+.loop:
+ ( rem ) ( ctr b a )
+ ( if ctr == 0 then done )
+ r> r> r> dup jz .done
+
+ ( rem a b ctr ) ( )
+ ( decrement counter )
+ lsr >r
+
+ ( rem a b ) ( ctr )
+ ( shift accumulator )
+ >r >r shl r@ #32 0x80000000i32 & jz .nocarry
+ #8 1i8 |
+.nocarry:
+ r> shl
+
+ ( rem a ) ( ctr b )
+ ( attempt subtraction )
+ >r dup r> r@ swap >r
+ ( rem rem b ) ( ctr b a )
+ swap - dup jn .next
+ swap r> #8 1i8 + >r
+.next:
+ drop
+ ( rem ) ( ctr b a )
+ jmp .loop
+
+.done:
+ ( rem a b ctr ) ( )
+ drop drop ;
+
+
( Divide an unsigned integer by another unsigned integer )
-( a b -- b/a )
+( a b -- a/b )
div_uu:
- ;
+ call divmod_uu swap drop ;
( Take one unsigned integer modulo another unsigned integer )
-( a b -- b%a )
+( a b -- a%b )
mod_uu:
- ;
+ call divmod_uu drop ;