Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Extended KotD #1: _ANDALSO
#1
You guys may have noticed that we haven't had any Keyword's of the Day for ages now.  The reason for this is really rather simple -- we basically covered the vast majority of keywords and ran out of topics to cover! 

Fortunately, as QB64PE progresses, new commands and functionality gets added over time, and now that we're up to version 3.13, it's probably about time to take a few moments and start going into better detail about what these new functions are, why they were added, and what a person might use them for.  To facilitate this, I'm just going to start at version 3.13 and work my way backwards, down to version 3.0 or so, and try and highlight one function per day, until I've basically covered them all for us.

For today's entry, let's talk about the newest LOGICAL OPERATOR -- _ANDALSO.

First, a little code to discuss:

Code: (Select All)
a = 1
b = 2
If a And b Then Print "A AND B are TRUE" Else Print "A AND B are FALSE"
If a _Andalso b Then Print "A _ANDALSO B are TRUE" Else Print "A _ANDALSO B are FALSE"

Now, as all you folks probably know, AND is a bitwise comparision tool, that compares bits between two values. It is NOT a logical comparision tool to determine if TRUE or FALSE exists.

1 AND 2 <--- both of these values are non-zero, so in QBASIC, their values are considered to be TRUE. Now, TRUE and TRUE should logically be TRUE. Right?

WRONG!!

As I mentioned before, these are NOT logical comparisons!

00000001 <--- 1, as written in binary
00000010 <--- 2, as written in binary
------------ <--- AND -- let's compare and AND the bits here
00000000 <--- the return value is 0 -- it's FALSE!

1 AND 2 = 0... It's FALSE!



So what's the solution here, if we don't want to deal with binary comparisons? The old method was to compare both against 0, as such:

Code: (Select All)
If 1 <> 0 And 2 <> 0 Then Print "It's TRUE"

IF the first value is not zero, AND the second value is not zero, then it's TRUE... This is how we always used to have to create logical comparisons, instead of just allowing for bitwise AND to mess things up by itself.



But now, we have a new logical operator: _ANDALSO

If 1 _ANDALSO 2 THEN PRINT "It's TRUE"

This basically does what the previous example does for us -- it compares both values against 0 to see if they're true, and if they're both true, then it assigns the end result as being true.

This is NOT bit-comparision -- use AND for that. _ANDALSO is simply logical comparison.

IF Happy _ANDALSO Sexy Then Life = Good



_ANDALSO -- logical comparison of two values (are they TRUE/non-zero, or FALSE/zero). They're that simple to understand and use.

https://qb64phoenix.com/qb64wiki/index.php/ANDALSO
Reply
#2
(05-05-2024, 09:20 PM)SMcNeill Wrote: You guys may have noticed that we haven't had any Keyword's of the Day for ages now.  The reason for this is really rather simple -- we basically covered the vast majority of keywords and ran out of topics to cover! 

Fortunately, as QB64PE progresses, new commands and functionality gets added over time, and now that we're up to version 3.13, it's probably about time to take a few moments and start going into better detail about what these new functions are, why they were added, and what a person might use them for.  To facilitate this, I'm just going to start at version 3.13 and work my way backwards, down to version 3.0 or so, and try and highlight one function per day, until I've basically covered them all for us.

For today's entry, let's talk about the newest LOGICAL OPERATOR -- _ANDALSO.

First, a little code to discuss:

Code: (Select All)
a = 1
b = 2
If a And b Then Print "A AND B are TRUE" Else Print "A AND B are FALSE"
If a _Andalso b Then Print "A _ANDALSO B are TRUE" Else Print "A _ANDALSO B are FALSE"

Now, as all you folks probably know, AND is a bitwise comparision tool, that compares bits between two values.  It is NOT a logical comparision tool to determine if TRUE or FALSE exists.

1 AND 2 <--- both of these values are non-zero, so in QBASIC, their values are considered to be TRUE.  Now, TRUE and TRUE should logically be TRUE.  Right?

WRONG!!

As I mentioned before, these are NOT logical comparisons!

00000001  <--- 1, as written in binary
00000010  <--- 2, as written in binary
------------  <--- AND -- let's compare and AND the bits here
00000000  <--- the return value is 0 -- it's FALSE!

1 AND 2 = 0...  It's FALSE!



So what's the solution here, if we don't want to deal with binary comparisons?  The old method was to compare both against 0, as such:

Code: (Select All)
If 1 <> 0 And 2 <> 0 Then Print "It's TRUE"

IF the first value is not zero, AND the second value is not zero, then it's TRUE...  This is how we always used to have to create logical comparisons, instead of just allowing for bitwise AND to mess things up by itself.



But now, we have a new logical operator:  _ANDALSO

If 1 _ANDALSO 2 THEN PRINT "It's TRUE"

This basically does what the previous example does for us -- it compares both values against 0 to see if they're true, and if they're both true, then it assigns the end result as being true.

This is NOT bit-comparision -- use AND for that.  _ANDALSO is simply logical comparison.

IF Happy _ANDALSO Sexy Then Life = Good



_ANDALSO -- logical comparison of two values (are they TRUE/non-zero, or FALSE/zero).  They're that simple to understand and use.

https://qb64phoenix.com/qb64wiki/index.php/ANDALSO

I rarely use bit-wise operators per se - I'm slack enough, and trusting enough, to let the system do that for me. But I can see that I may be tricked by this. I've always thought 1 AND 2 would be true, and probably worked around the strange results I got to make this fit! Thanks Steve!
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Please visit my Website at: http://oldendayskids.blogspot.com/
Reply
#3
Could this be a quasi stand in for the IMP logical operator? If Happy IMP Sexy then Life = Good
Reply
#4
One aspect Steve didn't mention in the short-circuiting functionality of `_AndAlso` (and `_OrElse`), which can be used to simplify code that would otherwise require multiple `IF` levels:

Code: (Select All)
' Normal implementation
IF handle < -1 THEN
    IF _WIDTH(handle) >= 640 THEN ...
END IF

' This doesn't work
IF handle < -1 AND _WIDTH(handle) >= 640 THEN ...

' This does work
IF handle < -1 _AndAlso _WIDTH(handle) >= 640 THEN ...

The code here is checking that an image handle is valid, and if it is then it checks that the width of that image is at least 640. The point of the `handle < -1` is to avoid the 'invalid handle' error you will get if you pass an invalid handle to `_WIDTH()`.

In the regular case, this requires two levels of `IF`s. You might be tempted to simply use the `AND` example I gave, but that doesn't work for two reasons:

1. `AND` always evaluates both sides of the equation, so even if `handle < -1` gives false, the `_WIDTH(handle) >= 640` side is still evaluated, so the error happens anyway.
2. The evaluation order of the `AND` is not guaranteed. The compiler might simply evaluate `_WIDTH(handle) >= 640` first, completely defeating the purpose of the `handle < -1` check.

In comparison the single `_AndAlso` version does work as intended. `_AndAlso` has 'short circuiting' behavior, so if the left side evaluates to false then the right side is not evaluated _at all_, since the result will always be false anyway. Additionally the evaluation order is guaranteed, the left side is always evaluated first before the right side. The combination means that you can use `_AndAlso` to completely avoid the 'invalid handle' error while still only using a single `IF` statement.
Reply
#5
(05-06-2024, 06:39 PM)DSMan195276 Wrote: `_AndAlso` has 'short circuiting' behavior, so if the left side evaluates to false then the right side is not evaluated _at all_, since the result will always be false anyway. Additionally the evaluation order is guaranteed, the left side is always evaluated first before the right side. The combination means that you can use `_AndAlso` to completely avoid the 'invalid handle' error while still only using a single `IF` statement.
For me, this is the most compelling reason.  One thing that almost always gets me from using other languages is that QB by default does not short circuit conditions.

Nice addition.
Reply




Users browsing this thread: 2 Guest(s)