Shop OBEX P1 Docs P2 Docs Learn Events
Multiply Signed numbers (Assembly) — Parallax Forums

Multiply Signed numbers (Assembly)

scottascotta Posts: 168
edited 2007-05-14 03:48 in Propeller 1
Does anyone have an Assembler signed integer math library posted ?


Scott

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-06 03:44
    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.
  • scottascotta Posts: 168
    edited 2007-04-06 05:36
    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
    
    
    
  • rjo_rjo_ Posts: 1,825
    edited 2007-04-06 05:48
    scotta,

    If you don't mind me asking...[noparse]:)[/noparse]

    Are you generally interested in numbers?

    Rich
  • scottascotta Posts: 168
    edited 2007-04-06 05:57
    With this chip I am.
  • rjo_rjo_ Posts: 1,825
    edited 2007-04-06 06:12
    Scotta,

    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
  • scottascotta Posts: 168
    edited 2007-04-06 06:14
    Thanks, it looks great, but I think it's broken....

    Will probably repost a better copy, go ahead and
    put it in the book.

    Scott
  • rjo_rjo_ Posts: 1,825
    edited 2007-04-06 06:24
    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
  • scottascotta Posts: 168
    edited 2007-04-06 06:48
    [noparse]:)[/noparse]

    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
    
    
  • scottascotta Posts: 168
    edited 2007-04-06 15:15
    Can anyone see whats wrong with this?

    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
    
    
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-06 15:29
    Try this for making a signed division from an unsigned one.
    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
    
    
  • scottascotta Posts: 168
    edited 2007-04-06 15:42
    Mike,

    I can't see why it does not work with a signed divisor.

    What am I missing ?
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-06 15:49
    scotta,
    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).
  • rjo_rjo_ Posts: 1,825
    edited 2007-04-06 17:08
    Scott....


    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
  • scottascotta Posts: 168
    edited 2007-04-06 19:07
    Rich

    What did you work out (in integer form). I'm a little lost

    Scott
  • rjo_rjo_ Posts: 1,825
    edited 2007-05-14 00:15
    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
    348 x 645 - 223K
  • rjo_rjo_ Posts: 1,825
    edited 2007-05-14 00:23
    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.

    Rich
  • rjo_rjo_ Posts: 1,825
    edited 2007-05-14 00:27
    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.

    Rich
  • rjo_rjo_ Posts: 1,825
    edited 2007-05-14 03:48
Sign In or Register to comment.