Shop OBEX P1 Docs P2 Docs Learn Events
Problem with IF...THEN statements — Parallax Forums

Problem with IF...THEN statements

cedtinsicedtinsi Posts: 45
edited 2011-04-05 12:48 in BASIC Stamp
Thank You and Welcome.

I have a problem with my code at the level of the IF...THEN statements.
Even when timeout is negative, the Stamp executes the commands as if timeout was positive; so it does not follow the conditions that I imposed.
Down below is the code.

Please Help.
Thank You.






' {$STAMP BS2}
' {$PBASIC 2.5}
pattern VAR Nib
timeout VAR Word
control VAR Word

beginning:
pattern=IND
DEBUG ? pattern, CR
DO
pattern=IND
DEBUG ? pattern, CR
LOOP UNTIL pattern=8
PAUSE 10
IF pattern=0 THEN
GOTO intern1
ENDIF

intern1:
timeout=50
DO
pattern=IND
DEBUG ? pattern, CR
timeout=timeout-1
DEBUG SDEC ? timeout
PAUSE 10
IF ((timeout=0)|(timeout<0)) THEN
GOTO beginning
ENDIF
IF (timeout>0) THEN
GOTO intern2
ENDIF
LOOP UNTIL pattern=2



intern2:
DO
pattern=IND
DEBUG SDEC ? timeout
timeout=timeout-1
LOOP UNTIL pattern=2
DEBUG "*",CR
IF ((timeout=0)|(timeout<0)) THEN
GOTO beginning
ENDIF
IF (timeout>0) THEN
GOTO intern4
ENDIF
intern4:
DO
pattern=IND
DEBUG ? pattern, CR
timeout=timeout-1
LOOP UNTIL pattern=1
DEBUG SDEC ? timeout
DO
control=timeout
DEBUG SDEC ? control
IF ( timeout < 0) THEN
GOTO beginning
ENDIF
IF (timeout>0) THEN
GOTO intern3
ENDIF
LOOP UNTIL pattern=3

intern3:
HIGH 11
LOW 10
PAUSE 1000
LOW 11
LOW 10

Comments

  • ercoerco Posts: 20,256
    edited 2011-04-04 09:25
    The Stamp's integer math doesn't easily give you the negative number you may expect: 1-2=255

    Plan accordingly. Sometimes it's safer to use 100 as your center "zero point" for a variable. Do all your math around that value, never letting it go below 0 or higher than 255 (for a BYTE variable). Then compare the final value to 100 and branch as needed.
  • vaclav_salvaclav_sal Posts: 451
    edited 2011-04-04 09:33
    Minor comment
    Timeout is generally defined / used / evaluated as reaching a value.
    For example 60 to timeout 0 - as you probably wanted to use it.

    Why would you wanted to check for LESS than timeout value?

    Vaclav

    PS Your code is looking better.
  • cedtinsicedtinsi Posts: 45
    edited 2011-04-04 10:09
    Thank You for devoting your precious time to help.

    I tested the code.
    I used some debug statements to get the value of timeout at some point in the code.
    It does give me the values of timeout that I expect; but can't do the right thing for that value of timeout, say, timeout is negative but it does what it should do when timeout is positive.
    The code would work as I want; I just need to make those IF...THEN statements work.
    So, my question is: why does the Stamp won't execute a simple conditional IF...THEN statement as that?
    I do not get that.

    Please Help.
    I need to make that IF...THEN statement work; in fact, it should be working right?

    Thank You
  • vaclav_salvaclav_sal Posts: 451
    edited 2011-04-04 17:28
    You need to take a look at this code snippet - all by itself, not even connected to your program.
    The IF statement evaluates from left to right , therefore if timeout = 0 is true the "or" will not even get evaluated.
    Logically - if you subtract 1 from timeout it wiil reach 0 first anyway.

    IF ((timeout=0)|(timeout<0)) THEN
    GOTO beginning
    ENDIF

    Please identify exactly which IF ... THEN is faling in your code..

    Vaclav
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2011-04-04 20:36
    From PBASIC Help --

    The Minimum operator (MIN) limits a value to a specified 16-bit positive minimum. The syntax of MIN is:

    Value MIN Limit

    Where Value is a constant or variable value to perform the MIN function upon and Limit is the minimum Value that value is allowed to be. When used in a statement like result = Value MIN Limit, its logic is, 'if Value is less than Limit, then make result = Limit; if Value is greater than or equal to Limit, make result = Value.' MIN works in positive math only; its comparisons are not valid when used on two’s complement negative numbers, since the positive-integer representation of a number like -1 ($FFFF in hexadecimal or 65535 in unsigned decimal) is larger than that of a number like 10 ($000A hexadecimal or 10 decimal). Use MIN only with unsigned integers. Because of the way fixed-size integers work, you should be careful when using an expression involving MIN 0. For example, result = 0 - 1 MIN 0 will result in 65535 because 0 - 1 = -1 (65535 in two's compliment math) and 65535 is greater the minimum boundary 0.
    value1  VAR     Word
    value2  VAR     Word
    
    Main:
      FOR value1 = 100 TO 0 STEP 10                 ' walk value1 from 100 to 0
        value2 = value1 MIN 50                      ' use MIN to clamp at 50
        DEBUG DEC ? value2 MIN 50                   ' show "clamped" value
      NEXT
      END
    


    [What's it going to take to get you to start Attaching your code instead of Posting it?]
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2011-04-04 21:49
    You might do it this way,

    IF timeout=0 OR timeout.bit15=1 THEN ...
    instead of
    IF ((timeout=0)|(timeout<0)) THEN...

    and
    IF (timeout.bit15 = 0) THEN...
    instead of
    IF (timeout>0) THEN...

    I think that would work in your current framework.

    Bit 15 indicates the status, 1 if negative, 0 if positive. In twos complement, the boundary between positive and negative occurs when that bit flips, between 32767=%0111111111111111 and -32768 = %1000000000000000.

    The above is not the only way to do it, as others have explained. You do have to see how the Stamp handles numbers. You can use the SDEC modifier to display a twos complement number, but the Stamp's internal comparisons treat all numbers as positive integers.
  • vaclav_salvaclav_sal Posts: 451
    edited 2011-04-05 10:12
    Just to keep things in perspective - my two cents worth.

    IF ( a= 0 | a <0 ) THEN
    or
    IF (a= 0 OR a<0 ) THEN

    accomplish same results.

    Both statements evaluate to true or false.

    If there is an error in coding logic, changing | to OR it will not resolve it.

    Unless I missed it, the value a is only decremented by 1 , therefore will reach 0 and the statement
    a<0 is immaterial as coded.

    Of course one could write IF(a<0 | a= 0) THEN...
    Maybe then the logical convolution would be more obvious.

    Vaclav
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2011-04-05 11:10
    Vaclav, I was suggesting that the OP use timeout.bit15=1 to indicate a rollover to a negative value, instead of the impossible timeout<0. There does not seem to be an obvious way that timeout could go below zero in the program, but on the other hand, I did not follow the code carefully through all the branches, and took the question at face value that such a test is necessary.

    The PBASIC syntax {IF a=b OR c=d THEN...} is documented, whereas the bitwise or "|" has to be used with caution. The Stamp evaluates {IF a=b | c=d THEN...} differently than {IF (a=b) | (c=d) THEN...} On the other hand, statements like, {IF a | b THEN...} or {IF a | b = c | d THEN...} are not problematic.
  • vaclav_salvaclav_sal Posts: 451
    edited 2011-04-05 12:48
    Tracy,
    no problem.
    Your post is just fine. I think this fellow is making progress and I was just trying to point out that both statements will work same - in this case.
    I would not want to give an impression that it will solve the alleged problem.
    Vaclav
Sign In or Register to comment.