Post Reply 
(42, all flavours) Integer Division - how?
12-20-2020, 03:22 AM (This post was last modified: 01-08-2021 03:05 PM by Albert Chan.)
Post: #47
RE: (42, all flavours) Integer Division - how?
DIV code, using REM. It work with signed arguments, both a and b.

Code:
00 { 42-Byte Prgm }
01▸LBL "DIV"    @  L     X     Y     Z     T
02 RCL ST Y
03 RCL ST Y     @        b     a     b     a
04 ÷
05 ENTER
06 IP           @    IP(q)     q     b     a
07 X>Y?
08 DSE ST X     @ floor(q) < 0, always skip
09 X<Y?
10 RTN
11 LSTO "q"
12 R↓
13 R↓
14 LSTO "b"
15 XEQ "REM"
16 RCL÷ "b"     @ remainder(a,b)/b
17 ENTER
18 SIGN         @ note: SIGN(0)=1
19 X>0?
20 CLX
21 RCL+ "q"     @ remainder(a,b)/b < 0 and q-1 or q
22 END

To handle signs of a, b, correction test: remainder(a,b)/b < 0 and q-1 or q

idiv(a, b) = idiv(sign(b)*a, |b|)      -- previously, code required positive divisor

remainder(a,b)/b
= remainder(a,|b|) / (sign(b)*|b|)
= sign(b) * remainder(a, |b|) / |b|
= remainder(sign(b)*a, |b|) / |b|

The code gives the same answer, as if we manually made b positive. Smile

Note: remainder(a,b)/b = fractional part of quotient, if integer part is closest to a/b, not floored.

Example:

4e33 39 + STO "u" 40 STO "v" XEQ "DIV"      → X = 1e32, Y = -0.025

With Y < 0, this meant closest integer for u/v is X+1
(-u)/(-v) gives exactly the same result of u/v, as expected.
u/v = X+1 - Y = 1e32 + 0.975

(-u)/v gives X = -1e32 - 1, Y = 0.025

With Y >= 0, closest integer for (-u)/v = X
u/(-v) gives exactly the same result of (-u)/v, as expected.
(-u)/v = X + Y = -1e32 - 0.975

Note: if u/v != floor(u/v), the code skipped REM, and return floor(u/v), u/v

100 16 XEQ "DIV"      → X = 6, Y = 6.25

Update: removed the unneeded NOP after DSE
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: (42, all flavours) Integer Division - how? - Albert Chan - 12-20-2020 03:22 AM



User(s) browsing this thread: 1 Guest(s)