News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

Confused by conditional statement.

Started by david, Dec 14, 2024, 09:30 PM

Previous topic - Next topic

david

Hi All,
I'm using what seemed like a fairly simple conditional statement in a piece of code but after many months I've just discovered it is not working as expected.

If mode=1 And count<2*stopset+1 And stmr>343 And parkflag=0 Then GoTo park

The above will jump to park even if count is >2*stopset+1
mode is Byte, parkflag is Byte, stmr is Word and count is SWord     Compiler version 4.0.3.8
I replaced  <2*stopset+1  with <stopset+stopset+1  but it still failed.
Replacing   <2*stopset+1  with a constant worked as did using a new variable as follows-
tempcalc=2*stopset+1
If mode=1 And count<tempcalc And stmr>343 And parkflag=0 Then GoTo park

So what is wrong with my first piece of code?

Regards to all,
David

trastikata

Hello david,

try using brackets for compound conditions

If mode=1 And count<(2*stopset+1) And stmr>343 And parkflag=0 Then GoTo park

RGV250

Hi,
You could also try nested if's rather than all in one line.

Bob

david

Thanks for the replies.
I did try brackets but without success.  Haven't tried nested Ifs.
I had wondered if it was something to do with the mix of signed and unsigned integers.  The workaround is trivial but it's always more satisfying if you can understand the problem.

Cheers,
David

david

#4
Just confirming that nested Ifs didn't work correctly.

Using an additional variable seems the best result so far-
tempcalc=stopset+stopset+1
If count<tempcalc And mode=1 And stmr>685 And parkflag=0 Then GoTo park

Even with the extra variable declared it uses 69 bytes less code than this-
If count<stopset+stopset+1 And mode=1 And stmr>685 And parkflag=0 Then GoTo park  (which doesn't work correctly)
69 bytes seems a lot of overhead especially for the little devices I use.  I could store recipes on that.....

So yes it's sorted but no - it's not understood.

Cheers,
David

John Drew

Just a whisker off topic but I have always found significantly less bytes used when using temporary variables to break up complex maths functions. It seems the same applies with complex 'if' statements.
John

top204

Without a code snippet showing the variable types and the device type, it is impossible to give an answer.

With expressions within a comparison, the compiler must use worse case scenarios and it will use 16-bit expression temporary stack variables if the variables used are Byte or Word types, and 32-bit or Float if the variables are larger.

Using seperate conditions and knowing that an expression will not overflow is a good way of saving flash memry, RAM, and time with multiple comparisons on all compilers.

Please give a compilable code snippet for the comparison to show what is not working as expected.

david

Hi guys,
John - I still get carried away trying to write concise code but as top204 has just confirmed it may cost you in bytes and speed. Breaking thigs down does seem to pay off.

top204  I don't think I can extract a compilable section of code as it's using variables scattered across 4k of code.

mode=Byte, parkflag=Byte, stmr=Word and count=SWord     Compiler version 4.0.3.8  Device 16F1824
The workaround is very simple and results in the lowest code usage even with the extra Byte variable used in the intermediate step.

Cheers,
David

top204

David

Make sure you are not mixing Signed and Unsigned variables and expressions within comparisons.

Remember, signed variables operate as 2's complement, so large values will be treat as signed, and a signed comparison on an unsigned expression result, and vice-versa, will not give the correct results.

david

I was indeed using mixed signed and unsigned variables in the expression (count=SWord) but the values used were only up to around 120 and nowhere near the 32768 crossover point of a SWord.  Assigning that particular term to an unsigned variable certainly fixed the issue.

David