Shop OBEX P1 Docs P2 Docs Learn Events
Math problem — Parallax Forums

Math problem

El PaisaEl Paisa Posts: 375
edited 2007-06-11 19:21 in Propeller 1
For those math gurus,
I need to solve this equation:
Y=sqr((X*X)-(range*range))
where·X·changes from 30 to 220, and range changes from 1 to 64

The result is to plot a point X,Y for different values of range.
(BTW, range is the output of a Parallax PING).

Any help will greatly appreciated.
·

Comments

  • El PaisaEl Paisa Posts: 375
    edited 2007-06-11 01:52
    My truly question is how to calculate a square root.
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-06-11 03:09
    [color=#000000]'[/color]
    [color=#000000]' Compute square-root of y[noparse][[/noparse]31..0] into x[noparse][[/noparse]15..0][/color]
    [color=#000000]'[/color]
    [color=#000000]root            mov     a,#0            'reset accumulator[/color]
    [color=#000000]                mov     x,#0            'reset root[/color]
    [color=#000000]                mov     t,#16           'ready for 16 root bits[/color]
     
    [color=#000000]:loop           shl     y,#1    wc      'rotate top two bits of y into accumulator[/color]
    [color=#000000]                rcl     a,#1[/color]
    [color=#000000]                shl     y,#1    wc[/color]
    [color=#000000]                rcl     a,#1[/color]
    [color=#000000]                shl     x,#2            'determine next bit of root[/color]
    [color=#000000]                or      x,#1[/color]
    [color=#000000]                cmpsub  a,x     wc[/color]
    [color=#000000]                shr     x,#2[/color]
    [color=#000000]                rcl     x,#1[/color]
    [color=#000000]                djnz    t,#:loop        'loop until done[/color]
     
    [color=#000000]root_ret        ret                     'square root in x[noparse][[/noparse]15..0][/color]
     
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • rjo_rjo_ Posts: 1,825
    edited 2007-06-11 04:19
    Thanks to El Paisa for the question... and Paul for the answer!
    I'll try to find a more efficient method[noparse]:)[/noparse]

    Rich
  • parskoparsko Posts: 501
    edited 2007-06-11 06:35
    El Paisa,

    The Propeller guts document will give you your answer. That is what Paul is quoting directly from above. I have done this in the past few months, so I recall my technique.

    I basically set up an assembly cog that contained all the math options (mult, div, sqrt, log table, sine table). I then call each routine as I need them. Each routine requires that you write your two numbers to the variable before calling. But it is really straightforward and not complicated. Once you get that, you can right another subroutine for the specific calculation you want to perform (you equation above, for instance). Then, you could simply write your two numbers to the variables, and call the routine, and you'll have your answer.

    NOTE: the divide, mult, and sqrt have limits to the maximum values you can use. This, you will need to play with accordingly. It will affect your accuracy as well. The easiest way I can explain is:

    divide: The numerator can be a 32 bit value, but the denominator can only be 16bit, and the answer will be 16 bit.
    Multiply: Both numbers can only be 16bit numbers (I think)

    I hope you get the idea. If you want, when I get home, I can post my code...

    -Parsko
  • El PaisaEl Paisa Posts: 375
    edited 2007-06-11 15:33
    Thanks all for the replies.
    Parsko, please post your code y example if possible.
  • parskoparsko Posts: 501
    edited 2007-06-11 19:21
    El Paisa,

    The "Temp_Water_Assy_A_005" file is the one that shows what and how I did the math.

    When it starts, in at the first sign of code, you will see calls to the subroutines. I assign values to the variable, as I described earlier. It first reads a value, in my case, I am performing math on an 8 bit temperature value. This could be any arbitrary 8 bit value. This math routine is designed to be as accurate as possible, without overflowing anything.

    The writes are simply to show what the value is for debugging, and could be removed to increase calculation speed. Each of the subroutines is copied from the Propeller guts document, nearly directly (I can't remember, but could check, but won't, sorry).

    There are 3 levels of routines working here. The top level ("tier 1")code I describe above, and is pretty obvious. Then there are the tier two routines, which organize the specific math calculations I want to perform. These are done in sequence according to the tier 1 routine. Each of the tier 2 routines may contain multiple math calculations, again, to perform something specific.

    Then, there is the tier 3 routines, which are fundemental multiply, divide, numexp ( have not had a need for sqrt yet, so it's not there).

    For example:
    Calculation 1 takes a value from the numexp routine and multiplies it by 1000, and dumps the remainder (or fraction). I do this, because I don't know how to work with a remainder, frankly said. This value is then used in further calculations. I did this for the reason that the multiply and divides don't work with remainders, but I want,ed more accuracy than just the non-remainder value.

    The rest of the calculations go on in the same manner. Honestly, it's been a while since I have written any code due to my 8 week old. I can't remember too much of the other routines, and didn't document them good at the time I wrote them... sorry again.

    Let me know if this makes sense. I eventually wanted to make something of a math cog that I could call at will, but it turns out to work best this way, since we are all doing specific math calculations for different reasons, and one "canned" math program will suit everyone's needs.

    Hope it helps. Let me know if you have more questions.

    -Parsko
Sign In or Register to comment.