Posts: 76
Threads: 19
Joined: Apr 2022
Reputation:
5
I am running this program to play with the mouse, just playing with things to understand it before trying to imbed it into something else.
Code: (Select All) $NOPREFIX
CONST FALSE = 0, TRUE = NOT FALSE
TYPE MouseType
EndX AS INTEGER
EndY AS INTEGER
StartX AS INTEGER
StartY AS INTEGER
LButDown AS INTEGER
RButDown AS INTEGER
OldLBut AS INTEGER
OldRBut AS INTEGER
END TYPE
SCREEN NEWIMAGE(1280, 720, 32)
DIM AS MouseType Mouse
DIM AS INTEGER highlight(500000)
DIM AS BIT Active
Mouse.OldLBut = --1
Active = FALSE
LINE (500, 200)-(600, 300), RGB(0, 0, 255), BF
DO
'LIMIT 120
DO WHILE MOUSEINPUT
LOOP
Mouse.StartX = MOUSEX
Mouse.StartY = MOUSEY
Mouse.LButDown = MOUSEBUTTON(1)
IF Mouse.StartX >= 500 AND Mouse.StartX <= 600 AND Mouse.StartY >= 200 AND Mouse.StartY <= 300 AND NOT Active THEN
GET (500, 200)-(600, 300), highlight()
PUT (500, 200), highlight(), PRESET
Active = TRUE
ELSEIF Active EQV Mouse.StartX < 500 OR Mouse.StartX > 600 OR Mouse.StartY < 200 OR Mouse.StartY > 300 THEN
GET (500, 200)-(600, 300), highlight()
PUT (500, 200), highlight(), PRESET
Active = FALSE
END IF
IF Mouse.LButDown AND NOT Mouse.OldLBut THEN
LOCATE 1, 1
PRINT Mouse.StartX, Mouse.StartY, Mouse.LButDown
END IF
Mouse.OldLBut = Mouse.LButDown
LOOP UNTIL INKEY$ = CHR$(27)
and it is working as expected with a box highlighting and not but I don't understand why this if statement needs EQV:
Code: (Select All) ELSEIF Active EQV Mouse.StartX < 500 OR Mouse.StartX > 600 OR Mouse.StartY < 200 OR Mouse.StartY > 300 THEN
GET (500, 200)-(600, 300), highlight()
PUT (500, 200), highlight(), PRESET
Active = FALSE
END IF
than the one I was trying to work with at first:
Code: (Select All) ELSEIF Active AND Mouse.StartX < 500 OR Mouse.StartX > 600 OR Mouse.StartY < 200 OR Mouse.StartY > 300 THEN
GET (500, 200)-(600, 300), highlight()
PUT (500, 200), highlight(), PRESET
Active = FALSE
END IF
My belief that If (false and True or True or True or True) should return a false with false and true.... condition.
Never used EQV before but the table on the wiki implies both should return false. Maybe someone can educate me where my logic has gone wrong? Many thanks
Posts: 2,177
Threads: 222
Joined: Apr 2022
Reputation:
104
12-11-2022, 02:47 PM
(This post was last modified: 12-11-2022, 02:48 PM by Pete.)
I avoid Boolean logic like the plague. Steve seems to like it, so I'll let him explain better if he reads this post.
I do like the use in this example; otherwise the difference is...
When you are using AND in the first condition, you only need to use ACTIVE once, because it combines with the 4 mouse pointer locations. In the second condition, you use OR to indicate the pointer has been moved outside the square, and since OR separates, you now need to place ACTIVE with each OR statement to achieve the same results...
Code: (Select All) ELSEIF Active AND Mouse.StartX < 500 OR Active AND Mouse.StartX > 600 OR Active AND Mouse.StartY < 200 OR Active AND Mouse.StartY > 300 THEN
So using EQV as you did with...
Code: (Select All) ELSEIF Active EQV Mouse.StartX < 500 OR Mouse.StartX > 600 OR Mouse.StartY < 200 OR Mouse.StartY > 300 THEN
...brilliantly reduces the repetition of ACTIVE in the prior use. +2 for that!
So when ACTIVE is FALSE we want to not re-enter that second condition again until ACTIVE becomes TRUE. The OR statements without EQV screw that up, because any one of the mouse location OR statements being true, that don't have an ACTIVE variable combined with it, makes the program flow return there again and again. Now with EQV, we use ACTIVE just once and compare it to EACH of the the 4 mouse position OR statements, so when just one of them is FALSE the whole condition is FALSE.
The basic why I would illustrate this is with the following group of OR statements with only the last of the 4 OR comparisons being true.
Code: (Select All) PRINT 1 > 2 OR 3 > 4 OR 5 > 6 OR 10 > 0
Active = -1 ' True.
PRINT Active EQV 1 > 2 OR 3 > 4 OR 5 > 6 OR 10 > 0
Active = 0 ' True.
PRINT Active EQV 1 > 2 OR 3 > 4 OR 5 > 6 OR 10 > 0
Notice how EQV nicely made the comparison if one of the OR statements is true, but ACTIVE is false, the condition is now FALSE.
Just for fun, I also included the Boolean table from the wiki:
Code: (Select All) ┌───────────────┬────────────────────────────────────────────────────────┐
│ Operands │ Logical operations │
├───────┬───────┼───────┬─────────┬────────┬─────────┬─────────┬─────────┤
│ A │ B │ NOT B │ A AND B │ A OR B │ A XOR B │ A EQV B │ A IMP B │
├───────┼───────┼───────┼─────────┼────────┼─────────┼─────────┼─────────┤
│ true │ true │ false │ true │ true │ false │ true │ true │
├───────┼───────┼───────┼─────────┼────────┼─────────┼─────────┼─────────┤
│ true │ false │ true │ false │ true │ true │ false │ false │
├───────┼───────┼───────┼─────────┼────────┼─────────┼─────────┼─────────┤
│ false │ true │ false │ false │ true │ true │ false │ true │
├───────┼───────┼───────┼─────────┼────────┼─────────┼─────────┼─────────┤
│ false │ false │ true │ false │ false │ false │ true │ true │
└───────┴───────┴───────┴─────────┴────────┴─────────┴─────────┴─────────┘
Pete
Posts: 2,698
Threads: 327
Joined: Apr 2022
Reputation:
217
https://qb64phoenix.com/forum/showthread.php?tid=1187 <-- Read this for EQV, and then see if you have any questions.
Posts: 76
Threads: 19
Joined: Apr 2022
Reputation:
5
12-11-2022, 03:03 PM
(This post was last modified: 12-11-2022, 03:08 PM by NasaCow.
Edit Reason: Clarifying
)
(12-11-2022, 02:47 PM)Pete Wrote: ...
Just for fun, I also included the Boolean table from the wiki:
Code: (Select All) ┌───────────────┬────────────────────────────────────────────────────────┐
│ Operands │ Logical operations │
├───────┬───────┼───────┬─────────┬────────┬─────────┬─────────┬─────────┤
│ A │ B │ NOT B │ A AND B │ A OR B │ A XOR B │ A EQV B │ A IMP B │
├───────┼───────┼───────┼─────────┼────────┼─────────┼─────────┼─────────┤
│ true │ true │ false │ true │ true │ false │ true │ true │
├───────┼───────┼───────┼─────────┼────────┼─────────┼─────────┼─────────┤
│ true │ false │ true │ false │ true │ true │ false │ false │
├───────┼───────┼───────┼─────────┼────────┼─────────┼─────────┼─────────┤
│ false │ true │ false │ false │ true │ true │ false │ true │
├───────┼───────┼───────┼─────────┼────────┼─────────┼─────────┼─────────┤
│ false │ false │ true │ false │ false │ false │ true │ true │
└───────┴───────┴───────┴─────────┴────────┴─────────┴─────────┴─────────┘
Pete
Just for fun, I looked at that table and tried NOT and AND with () around the OR conditions to make it work before I said "What the hell, can't be worse than a strobing box..." Imagine my surprise when EQV just worked...
Thank you for teaching the teacher. the double up the ANDs with the ORs make some sense to me!
(12-11-2022, 02:51 PM)SMcNeill Wrote: https://qb64phoenix.com/forum/showthread.php?tid=1187 <-- Read this for EQV, and then see if you have any questions.
I did read it before the post. Just didn't really explain the difference between AND and EQV to me well. If I get from Pete, then AND only works on the nearest OR operator (?) and EQV will work on the whole string of operations (?) Kind of like AND with OR multiply first and EQV gets added in at the end if I may use 5th grade math PEMDAS as a way to understand It is the teacher in me that wants to understand the WHY
Edit: I guess it really is the order of operations... I read it left to right and assumed that the one false on one side with the AND would make it all false but I guess I am messing up my Boolean order of operations...
Posts: 346
Threads: 24
Joined: Jul 2022
Reputation:
20
Hi NasaCow
yes your conditions in the control are very complex:
AND returns true only if both parameters are TRUE
EQV return true only if both parameters are the SAME (true or false is indifferent)
but watching nearer to the complex expression
you use 5 conditions...the first is ACTIVE
so until you use as first operator AND you can get TRUE (the block of code has been executed) only when Active is true plus the other conditions returns true on the other side of AND.
moreover putting 4 OR condition in sequence you must remember that OR returns FALSE only if both the parameters are FALSE otherwise it returns TRUE... so you can expect false only when all the parameters are false
F OR F gives F then F OR F gives F then F OR F gives false , at the end F AND F gives F while F EQV F gives T
(I do not remember the order of execution of Boolean operator, it seems to me that first is OR and after AND...)
here a code test
Code: (Select All) ' we make some tests
Rem AND versus EQV
Rem wiki info https://qb64phoenix.com/qb64wiki/index.php/EQV
DefInt I
Dim iActive, ImouseX, ImouseY
iActive = 0
Locate 1, 1: Print " iActive ImouseX ImouseY"
For iActive = -1 To 0 Step 1
' the first run has iActive true while the second turn has iActive false
ImouseX = 400: ImouseY = 100 ' ImouseX < 500 and ImouseY <200 are true
Locate , 7: Print " "; iActive; " "; ImouseX; " "; ImouseY;
If iActive And ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300 Then Print " AND works "; Else Print " AND rests";
' If iActive And (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300) Then Print " AND + () work "; Else Print " AND +() rest";
If iActive Eqv ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300 Then Print " EQV works " Else Print " EQV rests"
ImouseX = 600: ImouseY = 300 'All ImouseX and ImouseY are false
Locate , 7: Print " "; iActive; " "; ImouseX; " "; ImouseY;
If iActive And ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300 Then Print " AND works "; Else Print " AND rests ";
' If iActive And (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300) Then Print " AND + () work "; Else Print " AND +() rest ";
If iActive Eqv ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300 Then Print " EQV works " Else Print " EQV rests "
ImouseX = 700: ImouseY = 400 ' ImouseX>600 and ImouseY > 300 are true
Locate , 7: Print " "; iActive; " "; ImouseX; " "; ImouseY;
If iActive And ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300 Then Print " AND works "; Else Print " AND rests ";
' If iActive And (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300) Then Print " AND + () work "; Else Print " AND +() rest ";
If iActive Eqv ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300 Then Print " EQV works " Else Print " EQV rests "
Next iActive
For iActive = -1 To 0 Step 1
' the first run has iActive true while the second turn has iActive false
ImouseX = 400: ImouseY = 100 ' ImouseX < 500 and ImouseY <200 are true
Locate , 7: Print " "; iActive; " "; ImouseX; " "; ImouseY;
Print iActive And ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300, ;
' Print iActive And (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300), ;
Print iActive Eqv ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300
ImouseX = 600: ImouseY = 300 'All ImouseX and ImouseY are false
Locate , 7: Print " "; iActive; " "; ImouseX; " "; ImouseY;
Print iActive And ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300, ;
' Print iActive And (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300), ;
Print iActive Eqv ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300
ImouseX = 700: ImouseY = 400 ' ImouseX>600 and ImouseY > 300 are true
Locate , 7: Print " "; iActive; " "; ImouseX; " "; ImouseY;
Print iActive And ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300, ;
' Print iActive And (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300), ;
Print iActive Eqv ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300
Next iActive
you can give a look at the results.
Posts: 2,177
Threads: 222
Joined: Apr 2022
Reputation:
104
12-11-2022, 04:50 PM
(This post was last modified: 12-11-2022, 04:50 PM by Pete.)
@TempodiBasic
Che piacere vederti my friend from Italia!
Thanks for the better explanation. Boolean logic is not a must for programming, but it can make certain jobs, like in this neat mouse example, easier to code.
I want to get some more info on the SAME vs EQUALS above the bitwise comparison vs numeric values. For instance...
Code: (Select All) DIM AS _UNSIGNED _BYTE a, b
a = 2
b = 4
PRINT a EQV b, a = b
So a EQV b is -7 in this example. I do not work with bits so I don't see how that -7 result was calculated.
I'll probably find uses for this EQV keyword in my code now, just like I did with SGN(). Funny, I actually found some code from several years ago that I did use SGN() in, but then forgot about it. I even forgot this was a Keyword of the Day I read less than 2 weeks ago. I mean isn't aging great?... Sure, if you're a damn bottle of wine! Oh well...
Note: Similar for strings in JAVA ==, which can work with strings and differentiates how the string was made. For instance, == is False for a$ = "Pete" b$="P"+"e"+"t"+"e" a$ == b$ is FALSE, while a$ = b$ is TRUE. Just saying.
Pete
Shoot first and shoot people who ask questions, later.
Posts: 346
Threads: 24
Joined: Jul 2022
Reputation:
20
wow I googled and found the order of execution of the logical operator in QB
from first to last: NOT AND OR XOR EQV IMP
is this the same order of execution made by QB64pe? I think so, but I wait for developers response.
if so the above expression is
1. iActive AND ImouseX<500
2. result OR ImouseX>600
3. result OR ImouseY < 200
4. result OR ImouseY> 300
so in the case iActive = 0 and ImouseX = 400 and ImouseY = 100
1. 0 AND -1 --->0
2. 0 OR 0 --->0
3. 0 OR -1 --->-1
4. -1 OR 0 --->-1
Here there is a logical error if you need that iActive must be True to execute the block of code.
(here is like you are saying: if it is active and the mouse is at least at one of these positions (X<500, X>600, Y<200, Y>300) you do this...)
but using the ( ) ,surrounding the OR group of conditions, you can avoid this unwanted result... if you use AND is because you want that all the 2 parameters must be true to get back true as result.
while you use EQV when it is important to you to manage all the conditions that are both F or both T.
Here a test code that compares expression original AND + 3 OR ,with the use of () AND +(3 OR), the use of EQV (EQV + 3 OR), the use of () (EQV + (3OR))
Code: (Select All) ' we make some tests
Rem AND versus EQV
Rem wiki info https://qb64phoenix.com/qb64wiki/index.php/EQV
DefInt I
Dim iActive, ImouseX, ImouseY
iActive = 0
Locate 1, 1: Print " iActive ImouseX ImouseY"
For iActive = -1 To 0 Step 1
' the first run has iActive true while the second turn has iActive false
ImouseX = 400: ImouseY = 100 ' ImouseX < 500 and ImouseY <200 are true
Locate , 7: Print " "; iActive; " "; ImouseX; " "; ImouseY;
If iActive And ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300 Then Print " AND works "; Else Print " AND rests";
If iActive And (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300) Then Print " AND + () work "; Else Print " AND +() rest";
If iActive Eqv ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300 Then Print " EQV works "; Else Print " EQV rests";
If iActive Eqv (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300) Then Print " EQV +() works " Else Print " EQV +() rests "
ImouseX = 600: ImouseY = 300 'All ImouseX and ImouseY are false
Locate , 7: Print " "; iActive; " "; ImouseX; " "; ImouseY;
If iActive And ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300 Then Print " AND works "; Else Print " AND rests ";
If iActive And (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300) Then Print " AND + () work "; Else Print " AND +() rest ";
If iActive Eqv ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300 Then Print " EQV works "; Else Print " EQV rests ";
If iActive Eqv (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300) Then Print " EQV +() works " Else Print " EQV +() rests "
ImouseX = 700: ImouseY = 400 ' ImouseX>600 and ImouseY > 300 are true
Locate , 7: Print " "; iActive; " "; ImouseX; " "; ImouseY;
If iActive And ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300 Then Print " AND works "; Else Print " AND rests ";
If iActive And (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300) Then Print " AND + () work "; Else Print " AND +() rest ";
If iActive Eqv ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300 Then Print " EQV works "; Else Print " EQV rests ";
If iActive Eqv (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300) Then Print " EQV +() works " Else Print " EQV +() rests "
Next iActive
For iActive = -1 To 0 Step 1
' the first run has iActive true while the second turn has iActive false
ImouseX = 400: ImouseY = 100 ' ImouseX < 500 and ImouseY <200 are true
Locate , 7: Print " "; iActive; " "; ImouseX; " "; ImouseY;
Print iActive And ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300, ;
Print iActive And (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300), ;
Print iActive Eqv ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300; " ";
Print iActive Eqv (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300)
ImouseX = 600: ImouseY = 300 'All ImouseX and ImouseY are false
Locate , 7: Print " "; iActive; " "; ImouseX; " "; ImouseY;
Print iActive And ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300, ;
Print iActive And (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300), ;
Print iActive Eqv ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300; " ";
Print iActive Eqv (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300)
ImouseX = 700: ImouseY = 400 ' ImouseX>600 and ImouseY > 300 are true
Locate , 7: Print " "; iActive; " "; ImouseX; " "; ImouseY;
Print iActive And ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300, ;
Print iActive And (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300), ;
Print iActive Eqv ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300; " ";
Print iActive Eqv (ImouseX < 500 Or ImouseX > 600 Or ImouseY < 200 Or ImouseY > 300)
Next iActive
so the expression must pay attention to the order of execution of Logical operators to return the wanted result. As for all expression we can use () to modify the order of calculation.
Posts: 346
Threads: 24
Joined: Jul 2022
Reputation:
20
@Hi Pete
I am always fallen in love for this QB64pe community,
where I can talk, have good teacher, learn and expand my mind and my soul.
Yes I love BASIC, but there are so many dialects of it, only here I find so open persons to let me say, listen, try and learn from and with them.
That is fantastic!
Here my bitwise response to your question..
while we use values more than 2 opposite you are working at bitwise level... if you want to work at logical level you must define 2 only value in opposite condition and use them only . So comparison and other kind of operation must reduce the result to one of the 2 value used for logical operation....
in this sense False = 0 is OK, True = not False is good until in this logical universe we use only 0 for False and -1 for True
(as you can see with this code
print 0, not 0
)
as far away we go from this binary universe (universe of 2 items and not the universe of number with basis 2) as we get back so bad unwanted results .
the response in code to your example is this
Dim As _Unsigned _Byte a, b
a = 2
b = 4
Print a Eqv b, a = b
Print "Here the bitwise explanation! In logical math there are only TRUE and FALSE, no numbers"
Print String$(14, "0") + _Bin$(a)
Print String$(13, "0") + _Bin$(b)
Print _Bin$(-7)
as you can see it is a bitwise operation using EQV so the bits in the same position if they are the same you get 1 and if they are different you get 0.
But the compiler (interpreter) at the end translates the binary number to the decimal number... so you get a signed number -7 also if you have declared 2 unsigned byte numbers.
To logical operators you must pass logical values (T or F) so conditions that returns those logical values
for example
print NOT(a=b) EQV (a not b)
no sense to pass numbers in any basis (binary, octal etc) to LOGICAL operators.
If you want code in bitwise, please talk with expert of this like Steve or anyone else so ASM expert.
PS
JAVA is an universe that I would like explore... but I have 2 problems, the lack of time to use for, the fear to start a trip with no end.
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
(12-11-2022, 04:50 PM)Pete Wrote: @TempodiBasic
Che piacere vederti my friend from Italia! Mi piace vederti il mio amico d'Italia!
That's how I was taught in high school. I wouldn't have been able to come up with "vederti" without your help.
Umm... on topic, I would have never ventured using "EQV" for anything, and this is a new thing involving it to check if the mouse pointer is within a bounding box.
Posts: 2,177
Threads: 222
Joined: Apr 2022
Reputation:
104
(12-11-2022, 06:36 PM)mnrvovrfc Wrote: (12-11-2022, 04:50 PM)Pete Wrote: @TempodiBasic
Che piacere vederti my friend from Italia! Mi piace vederti il mio amico d'Italia!
That's how I was taught in high school. I wouldn't have been able to come up with "vederti" without your help.
Umm... on topic, I would have never ventured using "EQV" for anything, and this is a new thing involving it to check if the mouse pointer is within a bounding box.
Yeah, I absolutely love it for that application.
|