PASM math
This has had to come have up before, but I couldn't find a whole lot with the search...
I am looking for common math uses in PASM. I have found some algorithms, but there has to be better ones out there. I found propeller.wikispaces.com/MATH as well, but the functions are HUGE!
Here is what I found for multiplying:
problem: only 16 bit inputs, but fast
Here is mine:
problem: much slower especially when multiplying two large numbers
I also have one that works as a signed multiplier.
Here is the divider I found:
problem: it can't divide (for example) 350/100 ... unless a whole number is returned, the output is unexpected
And finally...
Square root I found:
and power I made:
problem: slow and dependent on [noparse][[/noparse]slow] multiply for large numbers
I'm a function-oriented-man so I have formatted these so the inputs are always par1, par2, etc. and the output is always in ret_val. It may make it slightly slower, but portability is very handy.
It seems there should be a collection of PASM math "functions" lying around somewhere. Any input?
I am looking for common math uses in PASM. I have found some algorithms, but there has to be better ones out there. I found propeller.wikispaces.com/MATH as well, but the functions are HUGE!
Here is what I found for multiplying:
problem: only 16 bit inputs, but fast
'----- MULTIPLY --------------------------------
' par1 * par2
' 16-bit max input, 32-bit results
multiply2 SHL par1, #16 ' get multiplicand into x[noparse][[/noparse]31..16]
MOV midx, #16 ' ready for 16 multiplier bits
SHR par2, #1 WC ' get initial multiplier bit into c
:loop IF_C ADD par2, par1 WC ' conditionally add multiplicand into product
RCR par2, #1 WC ' get next multiplier bit into c.
' while shift product
DJNZ midx, #:loop ' loop until done
MOV ret_val, par2 ' return product
multiply2_ret RET
Here is mine:
problem: much slower especially when multiplying two large numbers
'----- MULTIPLY --------------------------------
' par1 * par2
' 32-bit in/out ... slower than multiply2
multiply MOV ret_val, #0
CMP par1, #0 WZ ' if multiplyer of 0 return 0
IF_Z JMP #multiplyend
CMP par2, #0 WZ ' if multiplyer of 0 return 0
IF_Z JMP #multiplyend
CMP par1, par2 WZ, WC
IF_Z_OR_NC JMP #:skip
MOV accum, par1 ' these commands help speed up process by reducing number of loops
MOV par1, par2
MOV par2, accum
:skip
MOV midx, par2
:loop ADD ret_val, par1
DJNZ midx, #:loop
multiplyend
multiply_ret RET
I also have one that works as a signed multiplier.
Here is the divider I found:
problem: it can't divide (for example) 350/100 ... unless a whole number is returned, the output is unexpected
'----- DIVIDE ----------------------------------
' par1 / par2
divide SHL par2, #15 ' get divisor into y[noparse][[/noparse]30..15]
MOV midx, #16 ' ready for 16 quotient bits
:loop CMPSUB par1, par2 WC ' if y =< x then subtract it, set C
RCL par1, #1 ' rotate c into quotient, shift dividend
DJNZ midx, #:loop ' loop until done
MOV ret_val, par1 ' move to return
divide_ret RET
And finally...
Square root I found:
'----- SQUARE ROOT -----------------------------
' sqrt(par1)
root MOV accum, #0 ' reset accumulator
MOV par2, #0 ' reset root
MOV midx, #16 ' ready for 16 root bits
:loop SHL par1, #1 WC ' rotate top two bits of y
RCL accum, #1 ' ..into accumulator
SHL par1, #1 WC
RCL accum, #1
SHL par2, #2 ' determine next bit of root
OR par2, #1
CMPSUB accum, par2 WC
SHR par2, #2
RCL par2, #1
DJNZ midx, #:loop ' loop until done
MOV ret_val, par2 ' move to return
root_ret RET
and power I made:
problem: slow and dependent on [noparse][[/noparse]slow] multiply for large numbers
'----- POWER -----------------------------------
' par1^par2 -- par1 to-the-power-of par2
pow CMP par2, #0 WZ ' if power of 0 return 1
IF_Z MOV ret_val, #1
IF_Z JMP #powend
CMP par2, #1 WZ ' if power of 1 return par1
IF_Z MOV ret_val, par1
IF_Z JMP #powend
MOV accum, par1 ' make copy
MOV m2idx, par2 ' repeat par2 times
SUB m2idx, #1
MOV ret_val, par1
:loop MOV par1, ret_val ' use results in next use
MOV par2, accum
CALL #multiply
DJNZ m2idx, #:loop
powend
pow_ret RET
I'm a function-oriented-man so I have formatted these so the inputs are always par1, par2, etc. and the output is always in ret_val. It may make it slightly slower, but portability is very handy.
It seems there should be a collection of PASM math "functions" lying around somewhere. Any input?

Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
The Spin interpreter contains some functions that are sort of small but well, a bit slow. If you look at the FFT source (referenced in that page) there are some other routines. they are faster but also longer. You cannot have everything.
btw: I wrote that page
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
http://www.amazon.com/Math-Toolkit-Real-Time-Programming-Crenshaw/dp/1929629095/ref=sr_1_1?ie=UTF8&s=books&qid=1234243646&sr=1-1
Jack