fake 32 bit division for dummies
OK folks,
Please don't laugh and point fingers because I know this is something I should be able to handle myself. But I am stumped.
I have a constant
constantA CON 598760 'which is larger than 16 bits. (the 1's place is a zero and is insignificant)
I want to divide it with a variable
variableB VAR word ' that will range between 370 and 2000
result = constantA / variableB ' the result will range from about 300 to 1500
How do I handle this to get an integer result accurate to the 1's place? Knowing what the tenths place remainder is would be nice, but is not really necessary.
Thanks very much,
Lloyd
Please don't laugh and point fingers because I know this is something I should be able to handle myself. But I am stumped.
I have a constant
constantA CON 598760 'which is larger than 16 bits. (the 1's place is a zero and is insignificant)
I want to divide it with a variable
variableB VAR word ' that will range between 370 and 2000
result = constantA / variableB ' the result will range from about 300 to 1500
How do I handle this to get an integer result accurate to the 1's place? Knowing what the tenths place remainder is would be nice, but is not really necessary.
Thanks very much,
Lloyd

Comments
-Phil
I don't seem to be able to get that to work. Was the colon before the = a typo? I get a syntax error.
Also, with the constant being larger than 16 bits, I get a syntax error of the constant being too large.
I am still stumped. What do you think?
Thanks,
Lloyd
-Phil
598760 = 0x922E8
' {$STAMP BS2p} ' {$PBASIC 2.5} lowWord VAR Word highWord VAR Word result VAR Word denom VAR Word Init: lowWord = $22E8 highWord = $9 Main: denom = 370 GOSUB DoMath GOSUB ShowResult PAUSE 1000 denom = 2000 GOSUB DoMath GOSUB ShowResult PAUSE 1000 GOTO Main DoMath: result = ($FFFF / denom) * highWord result = result + (lowWord / denom) RETURN ShowResult: DEBUG CLS, ?result RETURNresult = (59876 / B * 10) + ((59876 // B * 10 + 0) /
' the last +0 is the 1s digit of the constant, which happens to be zero here.
Here are a couple of links that might help:
http://emesystems.com/BS2math2.htm#Reciprocal shortcut#2
http://emesystems.com/BS2math6.htm#Method3 double prec division 63 bits/31 bits
Cool! I gave it a try and it worked fine but truncated the remainder of the highword division. Came to me after a while.
I added a step to add the remainder from the highword division to the lowword before doint that division. Then it worked great.
DoMath:
result = ($FFFF / denom) * highWord
remainder = $FFFF - (result * denom)
result = result + ((lowWord + remainder) / denom)
RETURN
There is probably a better way to handle the remainder, but it works.
Thanks very much!
Lloyd
Yes, I see what you are doing. I was thinking of trying something like that but was coming up with something much more complicated.
Seems like so much of this 16 bit integer math is learning the tricks and then applying them. I am still having some trouble grasping/visualizing some of the math, but progress is happening.
Thanks everyone,
Lloyd
You mentioned that you might want to carry out the division to the tenths place. The decimal long division can be placed in a loop, as in the following example:
Q VAR WORD ' quotient B VAR WORD ' divisor D VAR WORD ' dividend n VAR NIB D = 59876 ' start with this, most significant digits of 598760 B = 370 fixedPointDecimalDivide: Q = 0 FOR n=0 TO 2 Q = Q * 10 + (D / B) D = D // B * 10 + 0 ' the + 0 would be needed if there other digits. NEXT IF D / B > 4 THEN Q = Q + 1 ' round off DEBUG CR, DEC Q ' e.g., Q=16183, decimal point implied, 1618.3 = 598760 / 370