Shop OBEX P1 Docs P2 Docs Learn Events
SPIN - limit maximum/minimum question — Parallax Forums

SPIN - limit maximum/minimum question

Ron CzapalaRon Czapala Posts: 2,418
edited 2011-05-31 09:58 in Propeller 1
I tried searching the forum, manuals and documentation for an answer but no luck...

I wonder why this code does not limit the value of temp to 20
  temp := 0
  repeat 30
    temp += 1 <# 20

This code does work of course:
  temp := 0
  repeat 30
    temp :=  temp + 1 <# 20

This also works...
  temp := 0
  repeat 30
     temp += 1 
     temp <#= 20

Comments

  • RaymanRayman Posts: 14,877
    edited 2011-05-31 06:26
    I'd guess it's the precedence of the operators...

    The limit 20 must have higher precedence, so it operates first, limiting the value of 1 to be less than 20...

    You could try using parenthesis to make sure the operators work in the order you want...
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2011-05-31 07:10
    Hmmmm! I tried putting parentheses around various parts of the expression, but the compiler gives me errors.

    (temp += 1) <# 20
    temp += 1 (<# 20)
    etc
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-05-31 07:52
    The operator precedence levels are shown below. Assignment operators have the lowest precedence, and they will always be executed after all the other operators. The "<#" operator is just below the "+" operator, so it will be executed after the addition. When in doubt use paretheses. However, the parentheses have to enclose complete expressions, which is why the compiler generates errors for the examples you show.
    precedence.GIF
    641 x 277 - 20K
  • Mike GreenMike Green Posts: 23,101
    edited 2011-05-31 07:53
    You can't write it the way you want. You can have

    temp ++
    temp <#= 20

    or you can have

    temp := (temp + 1) <# 20

    In Smalltalk, when you write the equivalent of "temp += 1", that statement carries temp forward so you can write "(temp += 1) <#= 20" and it works as you might think. Spin doesn't work that way. Spin carries the resulting value forward, so it would be like writing "5 <#= 20" if 5 was the new temp value.
  • schillschill Posts: 741
    edited 2011-05-31 07:55
    I don't think you will be able to use parentheses to get the affect you are looking for. I don't know of any language that would let you put parentheses around an assignment operator like that.

    Personally, I'd keep the equation simple and use something like:

    temp := temp++ <# 20

    edit: Mike beat me to it, with a better answer :) .
  • Mike GreenMike Green Posts: 23,101
    edited 2011-05-31 07:57
    schill,
    If you're going to use that form, you need to write "temp := ++temp <# 20"
  • schillschill Posts: 741
    edited 2011-05-31 08:09
    Mike Green wrote: »
    schill,
    If you're going to use that form, you need to write "temp := ++temp <# 20"

    You're right. Can I claim that I meant to write it your way and it's a typo (which is the truth)? Or, can I claim that I wrote it the way I did to implement a really fancy "phase shift" in the result?
  • Mike GreenMike Green Posts: 23,101
    edited 2011-05-31 08:13
    Of course it was a typo.
  • schillschill Posts: 741
    edited 2011-05-31 08:26
    Mike Green wrote: »
    Of course it was a typo.

    Yeah. That's my story. More of a "not typing what I was thinking" than an actual typo, I guess. :)
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-05-31 08:44
    That does raise an interesting question: when does the increment in temp++ actually occur? Just after the RHS has been evaluated and before the assignment, or just after the assignment? IOW, would this
    temp := temp++ <# 19

    have worked?

    -Phil
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-05-31 08:49
    temp++ will load the initial value of temp on the stack and store the incremented value to temp. The initial value of temp will then be limited to 19 and stored back to temp, so it won't work.

    I think the most efficient version is temp := (temp + 1) <# 20. I believe temp := ++temp <# 20 will generate the same number of bytecodes, but it results in a wasted store back to hub RAM. The number of cycles will probably be about the same for either expression.
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2011-05-31 08:53
    Thanks to all.

    I'm suprised that "temp += 1 <# 20" doesn't give an error and I don't get what "5 <#= 20" would evaluate to...

    I think the KISS (keep it simple stupid) methodology is the oftem the best. :surprise:
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-05-31 08:59
    temp += 1 <# 20 is equivalent to temp += (1 <# 20) or temp := temp + (1 <# 20).

    5 <#= 20 would generate an error because the left side of an assignment operator must be a variable.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-05-31 08:59
    I'm suprised that "temp += 1 <# 20" doesn't give an error...
    There may be times when this construct is useful, such as this:
    temp += increment <# 20

    Here, temp is augmented by the amount of increment, but by no more than 20.

    -Phil
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2011-05-31 09:40
    There may be times when this construct is useful, such as this:
    temp += increment <# 20
    Here, temp is augmented by the amount of increment, but by no more than 20.

    -Phil

    Phil, that does not work - temp will go past 20
    CON
      _CLKMODE = XTAL1 + PLL16X
      _XINFREQ = 5_000_000
    VAR
      long useser            'USB serial connection detected T/F
     
    OBJ
          pst     : "Parallax Serial Terminal"
    PUB Test1 | temp, incr 
      useser := false
      if ina[31] == 1                        ' RX (pin 31) is high if USB is connected
        pst.Start(115200)
        useser := true
      waitcnt(clkfreq * 1 + cnt)             'wait 3 seconds        
      if useser == true
        pst.Str(String(pst#cs, "Start", pst#NL))
     
      temp := 0
      incr := 1
      repeat 30
        temp += incr <# 20
        pst.dec(temp)
        pst.str(String(pst#NL))
        waitcnt(clkfreq/100 + cnt)  
    
    Start
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-05-31 09:54
    Phil, that does not work - temp will go past 20
    Right. The point of my post (read it again) is that temp cannot be incremented by more than 20 in one step.

    -Phil
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2011-05-31 09:58
    Right. The point of my post (read it again) is that temp cannot be incremented by more than 20 in one step.

    -Phil

    The "in one step" clarifies it!

    Thanks!
Sign In or Register to comment.