Author Topic: IF THEN issue using AND, I think I'm losing my mind!  (Read 7101 times)

0 Members and 1 Guest are viewing this topic.

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
IF THEN issue using AND, I think I'm losing my mind!
« on: December 10, 2021, 06:31:38 pm »
given the following:

Code: QB64: [Select]
  1.  
  2.  P.Mouse_over_R = 16
  3.  P.Mouse_over_B = 15
  4.  'The following IF THEN fails even though both values are TRUE(non 0)
  5.  IF P.Mouse_over_R  AND P.Mouse_over_B THEN
  6.    REM Mouse_Over_Data _MOUSEX, _MOUSEY, P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1
  7.   ELSE
  8.    _PRINTSTRING (0, 0), STR$(P.Mouse_over_R) + STR$(P.Mouse_over_B), _Display
  9.  
FAILS!

BUT given these values...

Code: QB64: [Select]
  1.  
  2.  P.Mouse_over_R = 9
  3.  P.Mouse_over_B = 7
  4.  'The following IF THEN passes
  5.  IF P.Mouse_over_R  AND P.Mouse_over_B THEN
  6.    REM Mouse_Over_Data _MOUSEX, _MOUSEY, P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1
  7.   ELSE
  8.    _PRINTSTRING (0, 0), STR$(P.Mouse_over_R) + STR$(P.Mouse_over_B), _Display
  9.   END IF
  10.  
WORKS?

So why? In both scenarios the values are non 0 but one works one doesn't?
Now if I add " > 0" to both checks it works all the time, but why is that needed?
What neuron-connections in my brain have failed and made me forget something about 'AND'?
Granted after becoming radioactive I only have a half-life!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #1 on: December 10, 2021, 06:39:51 pm »
Remember, AND is a binary operation.

Look at your values in binary:

16 = 10000
15 = 01111

AND those bytes...   you get 0 as a result.

16 AND 15 = 0.  It's a FALSE expression.



And the other value?
9 = 1001
7 = 0111

AND those bytes and you get 0001.

9 AND 7 = 1.   It's a TRUE expression.



What you want is:

IF P.MOR <> 0  AND P.MOB <> 0 THEN...
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #2 on: December 10, 2021, 07:10:49 pm »
OR

Code: QB64: [Select]
  1. P.Mouse_over_R = 16
  2. P.Mouse_over_B = 15
  3. 'The following IF THEN fails even though both values are TRUE(non 0)
  4. If P.Mouse_over_R Or P.Mouse_over_B Then
  5.     Print "Or works! for True Eval"; P.Mouse_over_R Or P.Mouse_over_B
  6.     Print "Or works! for False Eval"; P.Mouse_over_R Or P.Mouse_over_B
  7.  

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #3 on: December 10, 2021, 07:16:43 pm »
You don't want OR.

16 OR 0 = 16...  Which would make it true, and it's obvious Cobalt only wants it true if BOTH conditions are valid.

Just compare them as being <> 0 and you're good to go without false positives.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #4 on: December 10, 2021, 07:19:37 pm »
OK,

alt AND

If one then
  If the other then
     ' Do what you want when both are checked
  end if
end if

This skips checking the other case if first is already 0.

Offline George McGinn

  • Global Moderator
  • Forum Regular
  • Posts: 210
    • View Profile
    • Resume
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #5 on: December 10, 2021, 08:09:50 pm »
This should also work:

Code: QB64: [Select]
  1. IF P.Mouse_over_R AND NOT P.Mouse_over_B THEN
____________________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
American Association for the Advancement of Science (AAAS)

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #6 on: December 11, 2021, 12:34:02 am »
This should also work:

Code: QB64: [Select]
  1. IF P.Mouse_over_R AND NOT P.Mouse_over_B THEN

You guys all need to go back to logic school.  The above will NOT work.

X = 16
Y = 0

IF X AND Y THEN...   

What is wanted is a test for IF both conditions are TRUE THEN....

IF X AND NOT Y THEN...
IF 16 AND NOT 0 THEN
IF 16 AND -1 THEN
IF 16 THEN

Congrats!  You just passed your logic as TRUE, even though the second condition was FALSE.

X = 16
Y = -1

IF X AND NOT Y THEN
IF 16 AND NOT -1 THEN
IF 16 AND 0 THEN
IF 0 THEN

And, here you go again -- two true statements evaluate down to a FALSE decision.

Your program won't work because you simply can't be bothered to type <> 0 into your code.  Instead, you have to try to outsmart it by trying to insert convoluted logic to show that <> 0 is for beginners.

Keep things simple guys.  Either use <> 0, or break that IF into two lines as bplus has illustrated above and remove the AND from the situation completely.

Or else just write a LogicalAND function:

FUNCTION L_And (x , y)
   IF X <> 0 AND Y <> 0 THEN L_And = -1
EXIT FUNCTION

IF L_And(16, 15) THEN...

Look!  I reduced typing, don't have a bunch of those blasphemous <> 0 statements in my code, AND it works as intended!  Life doesn't get any better than that!
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #7 on: December 11, 2021, 12:43:01 am »
Well I guess Steve beat me to it.

This should also work:

Code: QB64: [Select]
  1. IF P.Mouse_over_R AND NOT P.Mouse_over_B THEN

No:
Code: QB64: [Select]
  1. For i = -1 To 0
  2.     For j = -1 To 0
  3.         If i Then
  4.             If j Then
  5.                 Print "i and j True"
  6.                 Print "i And Not j = "; (i And Not j)
  7.                 Print
  8.             Else
  9.                 Print "i True j False"
  10.                 Print "i And Not j = "; (i And Not j)
  11.                 Print
  12.             End If
  13.         Else
  14.             If j Then
  15.                 Print "i False j True"
  16.                 Print "i And Not j = "; (i And Not j)
  17.                 Print
  18.             Else
  19.                 Print "i and j False"
  20.                 Print "i And Not j = "; (i And Not j)
  21.                 Print
  22.             End If
  23.         End If
  24.     Next
  25.  

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #8 on: December 11, 2021, 01:07:37 am »
Thanks Steve, guys.  Sometimes I wonder if I'm experiencing the early onset of Alzheimer's. Guess I'll have to bring it up with DR next time.... if I remember that is....

Yeah both R and B have to be >0 otherwise it causes a Subscript out of range error within the routine Mouse_Over_Data. Which is odd cause the map area is the only place that IF THEN is ran and if R has a value then B has to have one too(in that area, R(ed) represents X value and B(lue) represents Y value), but when I just had an R check anytime you saved or loaded a map it pulled the subscript out of range if the mouse was over the map area. Could have just been an issue of order of operations though. If I would have moved that IF THEN to the top of the loop before the possibility of SAVE or LOAD it might not have happened. The mysteries of the universe that we shall never know!(or care about probably)
Granted after becoming radioactive I only have a half-life!

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #9 on: December 11, 2021, 10:49:30 am »
I should say (and I think that I'm in agreement with Steve, though I'm not sure of that!):

If variables are numbers (16 & 15) in this case, then always use equations:
     as Steve's IF P.MOR <> 0  AND P.MOB <> 0 THEN...
     The Boolean algebra is done after the equations are worked out.

Only use Boolean algebra (ie True or False only) when the variables are strictly Booleans (0 or -1 in QB64), eg:
     IF P%% AND NOT Q%% THEN...

Then you can't go wrong.


Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #10 on: December 11, 2021, 10:51:45 am »
I should say (and I think that I'm in agreement with Steve, though I'm not sure of that!):

If variables are numbers (16 & 15) in this case, then always use equations:
     as Steve's IF P.MOR <> 0  AND P.MOB <> 0 THEN...
     The Boolean algebra is done after the equations are worked out.

Only use Boolean algebra (ie True or False only) when the variables are strictly Booleans (0 or -1 in QB64), eg:
     IF P%% AND NOT Q%% THEN...

Then you can't go wrong.

100% in agreement with all you said here.  👍
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Stuart

  • Newbie
  • Posts: 11
    • View Profile
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #11 on: December 14, 2021, 05:13:33 am »
If the main purpose is to make sure that neither value is zero, instead of this : 
IF P.MOR <> 0  AND P.MOB <> 0 THEN...

wouldn't this work just as well and be more simple, shorter, and faster if it was in a loop?
IF P.MOR * P.MOB THEN...

Just wondering...

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #12 on: December 14, 2021, 07:22:22 am »
If the main purpose is to make sure that neither value is zero, instead of this : 
IF P.MOR <> 0  AND P.MOB <> 0 THEN...

wouldn't this work just as well and be more simple, shorter, and faster if it was in a loop?
IF P.MOR * P.MOB THEN...

Just wondering...

It would, with one little -- but vitally important - caveat attached:

BE ALERT OF OVERFLOW VALUES!!  THEY COULD GIVE FALSE RESULTS!!

For example, let's just use an _UNSIGNED _BYTE as an example.

_DEFINE A TO Z AS _UNSIGNED _BYTE
A = 16
B = 16

IF A * B THEN....

Now, A * B = 256.  It's JUST the perfect number that if our IF is bound by unsigned bytes, that it's going to overflow to become 0.  All at once, those two TRUE statements just became an unintended FALSE statement.



Now, with that caveat said, I'd also like to say, "I don't have a clue what variable TYPE an IF statement actually uses for internal calculations."  When we do A * B, is the intermittent result that we compare against 0 an _UNSIGNED _BYTE like the two initial variable types?  Is it a LONG?  A _FLOAT??

Honestly, I don't have a clue.  I know I've dug into the question before in the past, but my poor memory can't supply the answer for me at this exact moment.  All I'm certain of is that IF A * B ends up being the *exact* limit of that variable type + 1, it's going to overflow to become 0.  In 99.998% of all cases, it may be a completely moot issue as that internal value is a LONG and you're multiplying two BYTES together -- which will NEVER overflow -- but I'd prefer not to take a chance on it.  When that rare 0.002% glitch shows up where my code DOES multiple two values together that perfectly hit the overflow value back to 0, I know I'd have a three day marathon of debugging and pulling my poor hair out, looking for the issue.

IF A <> 0 AND B <> 0 THEN....    <--- Never any issues with this, and it's actually quite readable and easy to understand.

IF A * B THEN....   <--- This might run faster and be shorter code, but there's always the chance that SOMETIME, it's going to overflow.  And, I know myself -- when it does, something like this would drive me absolutely insane trying to find it and debug it.  Because, after all, it works perfectly well all the rest of the time!
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #13 on: December 14, 2021, 07:25:49 am »
Just an amateur's point of view passing by here, don't mind me, just that:

Code: QB64: [Select]
  1. IF A <> 0 AND B <> 0 THEN

looks OK in this language, but to dis-ambiguate everything, I would use more parentheses so its easier on the eye and on the brain: (plus this is not ambiguous in any language)

Code: QB64: [Select]
  1. IF ((A <> 0) AND (B <> 0)) THEN

On the other hand, stuff like

Code: QB64: [Select]
  1. IF A * B THEN

is a sentence without a verb. Source code should never make me do the work of filling in hidden meanings.
You're not done when it works, you're done when it's right.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: IF THEN issue using AND, I think I'm losing my mind!
« Reply #14 on: December 14, 2021, 07:43:03 am »
I still think, if folks want LOGICAL comparisons, they really should just write a couple of simple logic functions and then use those:

Code: QB64: [Select]
  1. a = 1
  2. b = 2
  3. Print a And b, __AND(a, b)
  4. Print a Or b, __OR(a, b)
  5.  
  6. 'LOGICAL FUNCTIONS FOR AND/OR
  7. Function __AND (x, y)
  8.     If x <> 0 And y <> 0 Then __AND = -1
  9.  
  10. Function __OR (x, y)
  11.     If x <> 0 Or y <> 0 Then __OR = -1

These only return -1 or 0 values for TRUE or FALSE, and they don't do bit-comparison math on our values.  They just give you the logical return without any regard for the bitwise results QB64 normally gives us.
« Last Edit: December 14, 2021, 09:21:28 am by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!