There's an unsigned multiply routine that's in the "Propeller Guts" document, but no signed multiply. It's easy enough to make a signed multiply routine using the NEG/NEGZ/NEGC and ABS instructions.
Try this for making a signed division from an unsigned one.
There's no overflow checking though.
Divide32x32 mov _sa,NUMA ' GET A SIGNshl NUMA,#1wc,NRnegc NUMA,NUMA
mov _sb,NUMA ' GET B SIGNshl NUMB,#1wc,NRnegc NUMB,NUMB
xor _sa,_sb ' Compute result sign' *** Now on to unsigned division mov ST0,#32mov ST1,#0' Do unsigned division
:loop shl NUMA,#1wcrcl ST1,#1cmpsub ST1,NUMB wc,wrrcl ST2,#1djnz ST0,#:loop
' *** End of unsigned divisionshl _sa,#1wc,NR' Apply result signnegc NUMA,ST2
Divide32x32_ret ret
Well.....that certainly was fast. I'm working on assembly... and I will be an expert by the time I get done... [noparse]:)[/noparse]
How many Earth days do you want to wait?
I worked it out in integer form... and I haven't checked to see if there is any other logic required for decimated numbers... my brain says no... but I haven't thought about it for a couple of years.
The idea is to compare the computational burden of computing a consecutive series of equal ordered exponential terms. The method is expandable to full exponential equations, but the equations have to be structured right (which is always possible... but never done)... the longer the series the higher the gain... and by analogy the more complex the exponential equation the higher the gain. The key is that somewhere in the solution space there has to be area of interest that contains a consecutive series of root terms.
If you want me to do it, the easiest way to show you the trick is to ask you to limit your algorithm to integers only... then take a small array... say 10 consectuive integers and calculate the exponents... and you need to put a counter in to get a total number of instructions required to do that.
And then put the whole thing in workable code... knowing that you are doing that... I could easily rewrite the routine. Probably. I might need a little help.
I think there are some important real world applications for this. It is neat. But it could be that someone has figured out a better way and put it into in general circulation.
Sorry this took so long. I was trying my best lame approach to putting this in Propeller Assembly... still thinking about it.
This basically shows how to generate exponents through a sum of differences method... this is what Babbage was trying to do with his difference engine... but I think he got his math screwed up... first time around.
By the way... any help coding this in assembly would be greatly appreciated [noparse]:)[/noparse]... for da Book.
I promised to show you a trick... here's how it would have gone...
I ask you to think of a number between 2 and 101... and don't tell anyone... then I will send you a program that will compute the cube of that number in the most efficient way possible and display it on your screen.
BUT I took so long... I didn't think a joke would be quite appropriate.
The important point is that the seeds must be computed... so you don't have to start with x= 2. You can start with x equal to anything... the computation of the seeds is fixed over-head related to the power of the exponent
So, there are some over-head calculations... which aren't shown.
Comments
Multiply16x16S ''RESULT IN numA mov ST1,#0 ''SETUP mov _sx,#0 mov _sy,#0 shl numA,#1 wc ''GET X SIGN negc numA,numA if_c mov _sx,#1 shl numB,#1 wc ''GET Y SIGN shr numB,#1 negc numB,numB if_c mov _sy,#1 mov ST2,#31 ''SETUP LOOP shr numB,#1 wc :mloop if_c adds ST1,numA wc ''LOOP rcr numB,#1 wc djnz ST2,#:mloop cmp _sx,_sy wz ''RESIGN mov numA,ST1 if_nz neg numA,numA Multiply16x16S_ret ret
If you don't mind me asking...[noparse]:)[/noparse]
Are you generally interested in numbers?
Rich
That is beautiful code... I forgot to ask you how long it took you to write.
If you get to the point that you find the math more interesting than the application...let me know[noparse]:)[/noparse]
Would it be ok for me to use your code... in my E-book project?
Rich
Will probably repost a better copy, go ahead and
put it in the book.
Scott
Before you go to bed... I have one more question?
I learned a trick... how to accelerate calculations based on exponential functions. It is absolutely amazing.
Would you be interested in seeing it? not tonight of course.
Be careful how you answer my question... because first you would have to give me an exponential function... in assembly.
Rich
Cam Thompson, Micromega Corporation
'------------------------------------------------------------------------------ ' _Exp fnumA = e ** fnumA ' _Exp10 fnumA = 10 ** fnumA ' _Exp2 fnumA = 2 ** fnumA ' changes: fnumA, flagA, expA, manA, fnumB, flagB, expB, manB ' changes: mt1, mt2, mt3, mt4, mt5 '------------------------------------------------------------------------------ _Exp call #_FMulI ' e ** fnum long 1.442695041 jmp #_Exp2 _Exp10 call #_FMulI ' 10 ** fnum long 3.321928095 _Exp2 call #_Unpack ' unpack variable if_c jmp #_Exp2_ret ' check for NaN if_z mov fnumA, One ' if 0, return 1.0 if_z jmp #_Exp2_ret mov mt5, fnumA ' save sign value call #_FTrunc ' get positive integer abs mt4, fnumA mov fnumA, mt5 call #_Frac ' get fraction call #_Unpack neg expA, expA ' get first 11 bits of fraction shr manA, expA mov mt1, manA ' shr mt1, #17 ' get table offset and mt1, TableMask add mt1, AlogTable ' get table address call #float18Bits ' remainder = lower 18 bits mov mt2, fnumA call #loadTable ' get fraction from log table call #_FAddI ' add 1.0 long 1.0 call #_Unpack ' align fraction mov expA, mt4 ' use integer as exponent call #_Pack test mt5, Bit31 wz ' check if negative if_z jmp #_Exp2_ret mov fnumB, fnumA ' yes, then invert mov fnumA, One call #_FDiv _Exp_ret _Exp10_ret _Exp2_ret ret
Its Mikes divide routine with an attempt for signed number support.
The resulting divide works, but the re-sign code does not work.
NUMA=NUMA/NUMB
Divide32x32 ''GET A SIGN mov _sa,#0 shl NUMA,#1 wc,NR if_c neg NUMA,NUMA if_c mov _sa,#1 ''GET B SIGN mov _sb,#0 shl NUMB,#1 wc,NR if_c neg NUMB,NUMB if_c mov _sb,#1 ''DIVIDE mov ST0,#32 mov ST1,#0 :loop shl NUMA,#1 wc rcl ST1,#1 cmpsub ST1,NUMB wc,wr rcl ST2,#1 djnz ST0,#:loop ''RESIGN cmps _sa,_sb wz if_z neg ST2,ST2 mov numA,ST2 Divide32x32_ret ret
There's no overflow checking though.
Divide32x32 mov _sa,NUMA ' GET A SIGN shl NUMA,#1 wc,NR negc NUMA,NUMA mov _sb,NUMA ' GET B SIGN shl NUMB,#1 wc,NR negc NUMB,NUMB xor _sa,_sb ' Compute result sign ' *** Now on to unsigned division mov ST0,#32 mov ST1,#0 ' Do unsigned division :loop shl NUMA,#1 wc rcl ST1,#1 cmpsub ST1,NUMB wc,wr rcl ST2,#1 djnz ST0,#:loop ' *** End of unsigned division shl _sa,#1 wc,NR ' Apply result sign negc NUMA,ST2 Divide32x32_ret ret
I can't see why it does not work with a signed divisor.
What am I missing ?
At the end of the routine you posted
cmps _sa,_sb wz if_z neg ST2,ST2
This should be
cmps _sa,_sb wz if_nz neg ST2,ST2
In the future, when you have a routine and you're not getting what you expect, please post the input values and the output value(s).
Well.....that certainly was fast. I'm working on assembly... and I will be an expert by the time I get done... [noparse]:)[/noparse]
How many Earth days do you want to wait?
I worked it out in integer form... and I haven't checked to see if there is any other logic required for decimated numbers... my brain says no... but I haven't thought about it for a couple of years.
The idea is to compare the computational burden of computing a consecutive series of equal ordered exponential terms. The method is expandable to full exponential equations, but the equations have to be structured right (which is always possible... but never done)... the longer the series the higher the gain... and by analogy the more complex the exponential equation the higher the gain. The key is that somewhere in the solution space there has to be area of interest that contains a consecutive series of root terms.
If you want me to do it, the easiest way to show you the trick is to ask you to limit your algorithm to integers only... then take a small array... say 10 consectuive integers and calculate the exponents... and you need to put a counter in to get a total number of instructions required to do that.
And then put the whole thing in workable code... knowing that you are doing that... I could easily rewrite the routine. Probably. I might need a little help.
I think there are some important real world applications for this. It is neat. But it could be that someone has figured out a better way and put it into in general circulation.
Thanks again,
Rich
What did you work out (in integer form). I'm a little lost
Scott
Sorry this took so long. I was trying my best lame approach to putting this in Propeller Assembly... still thinking about it.
This basically shows how to generate exponents through a sum of differences method... this is what Babbage was trying to do with his difference engine... but I think he got his math screwed up... first time around.
By the way... any help coding this in assembly would be greatly appreciated [noparse]:)[/noparse]... for da Book.
Rich
I ask you to think of a number between 2 and 101... and don't tell anyone... then I will send you a program that will compute the cube of that number in the most efficient way possible and display it on your screen.
BUT I took so long... I didn't think a joke would be quite appropriate.
Rich
So, there are some over-head calculations... which aren't shown.
Rich