Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 14:53 16 Nov 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Bitwise & Logical AND & OR

Author Message
MustardMan

Senior Member

Joined: 30/08/2019
Location: Australia
Posts: 175
Posted: 11:39am 21 Nov 2020
Copy link to clipboard 
Print this post

In my code I have a number of debug statements which I can activate by assigning a bit value to a variable, like this...
debug = &b0010  ' print all incoming bytes

Later doing something like
IF (debug AND &b0010) THEN PRINT "Rx=";r$
IF (debug AND &b0001) THEN PRINT "Tx=";t$
which works great. I can output multiple debug statements by simply declaring the correct value for 'debug'. For example in the above I could assign 'debug=&b0011' to output both Tx & Rx debug messages, or 'debug=&b0001' for Tx only, or 'debug=&b0000' for no messages.

Then I had a problem...
IF (debug AND &b0010) AND (LEN(r$) > 0) THEN PRINT "Rx=";r$
because I don't want to print out empty strings.

But this never executes.

(weak example, but illustrates the point).

If we go through evaluating each part:
debug = 2 : r$="ABC"
PRINT (debug AND &b0010)  =>  2 [true]
PRINT (LEN(r$) > 0)  => 1 [true]

One would expect that an expression IF true AND true THEN statement would execute said statement.

However: PRINT 2 AND 1  => 0 [false]

From a bitwise evaluation this is correct (of course).

However, the intent from reading the statement
IF condition1 AND condition2 THEN ...
does not evaluate as expected, and to make it follow my intent, I would have to write
IF condition1 OR condition2 THEN...
.... completely backwards from how one would expect (from reading it) it should!

I know I could get around this issue by writing
IF ((debug AND &b0010) > 0) AND (LEN(r$) > 0) THEN...
but that adds what I consider ancillary 'fluff' to an otherwise fairly straight forward looking statement.

I did read a thread that mentioned the possible use of ~ as a bitwise NOT, and the word NOT as a logical NOT, but I don't think it ever progressed. I like the C way of handling bitwise and logical: & and | for bitwise, and && and || for logical... I don't think basic will ever go down that route though: there would be way too much legacy code that would break if AND and OR were dedicated to be either one or the other.

Guess I'm stuck with 'the fluff'!!

Cheers,
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3308
Posted: 12:43pm 21 Nov 2020
Copy link to clipboard 
Print this post

Yes, sorry Owen, you are stuck with the fluff.

You can blame Bill because this behaviour comes from Microsoft BASIC.  Most times AND works fine but you have hit on an example of where it does cause trouble.

And before anyone mentions it - the NOT operator in MMBasic should also be a bitwise invert but instead it is a logical inversion.

Geoff
Geoff Graham - http://geoffg.net
 
RetroJoe

Senior Member

Joined: 06/08/2020
Location: Canada
Posts: 290
Posted: 01:09pm 21 Nov 2020
Copy link to clipboard 
Print this post

Isn’t this the same kind of natural-to-computer language “semantic inversion” that happens with SQL?

Business User says: “I need a report of all the red and blue cars we sold”
IT Guy writes: “SELECT * FROM CarSales WHERE Color=‘Red’ OR Color=‘Blue’”
Enjoy Every Sandwich / Joe P.
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4147
Posted: 01:16pm 21 Nov 2020
Copy link to clipboard 
Print this post

  MustardMan said  
IF (debug AND &b0010) AND (LEN(r$) > 0) THEN PRINT "Rx=";r$
because I don't want to print out empty strings.

Maybe this is "better" as a workaround:
IF (debug AND &b0010) THEN IF (LEN(r$) > 0) THEN PRINT "Rx=";r$


(I hope I got the syntax right)

John
 
Bowden_P
Senior Member

Joined: 20/03/2019
Location: United Kingdom
Posts: 162
Posted: 01:24pm 21 Nov 2020
Copy link to clipboard 
Print this post

Hi MustardMan,
Yes - I've had the same problem with unexpected "IF" statement functionality. I keep a file of unexpected MMBasic behaviours as I find them - here is the note I have for "IF", involving flag manipulations :-

"IF" expression limitations.
---------------------------
The "IF expression THEN" command seems limited in what it can evaluate to the expression TRUE state.
i.e. This works for AND-ing:-
IF (Flags% AND Cal_Volts_New_OK.Fl%) THEN     ' If the Cal. was successful, for Volts
 IF (Flags% AND Cal_Amps_New_OK.Fl%) THEN    ' AND Current, then
   gui enable Cal_VI_Details.PB%             ' enable the "Details" button.
   ENDIF
  ENDIF

but this doesn't :-

IF (Flags% AND Cal_Volts_New_OK.Fl%) AND (Flags% AND Cal_Amps_New_OK.Fl%) THEN ' If the Cal.
 gui enable Cal_VI_Details.PB%             ' was successful, enable the "Details" button.
ENDIF

"IF" works reliably for the sort of expression A=B, or A>=5, or just a single expression that evaluates to a single TRUE or FALSE state.

To realise the OR condition, use the ELSEIF instruction :-
i.e.
IF (Flags% AND Cal_Volts_New_OK.Fl%) THEN     ' If the Cal. was successful, for Volts
ELSEIF (Flags% AND Cal_Amps_New_OK.Fl%) THEN  ' OR Current, then
 gui enable Cal_VI_Details.PB%               ' enable the "Details" button.
ENDIF

This expression DOES work, despite its length :-
IF (X%>=178) AND (X%<=622) AND (Y%>=330) AND (Y%<=410) THEN

"IF" statement seems to need a =,<,>,<> somewhere for good functionality.

The shorthand "IF Count% THEN" evaluates TRUE for Count%<>0.

And yes Geoff, - I have been caught by wrongly assuming "NOT" was a bitwise operator!

With regards, Paul.
Nothing so constant as change.
 
MustardMan

Senior Member

Joined: 30/08/2019
Location: Australia
Posts: 175
Posted: 08:49pm 21 Nov 2020
Copy link to clipboard 
Print this post

Another way of doing it for AND is "*" (multiplication).

debug = 2 : r$="ABC"

IF (debug AND &b0010) * (LEN(r$)>0) THEN ...  ' result is 2, which is true


And an alternate for OR is "+" (addition).

The downside is using "+" and "*" cloud the programmers intent.
Having been in the unfortunate circumstance of having to debug someone elses uncommented and poorly written code I'm pretty big on writing clear, concise and commented code!

IF (statement1) + (statement2) THEN ...   ' OR
IF (statement1) * (statement2) THEN ...   ' AND

So there are a couple of work-arounds due to Bills original lack of foresight.

I guess that is why 'later' languages are almost always better implemented than 'earlier' ones.

Cheers,

EDIT:
Using "+" in place of logical OR does not always work, because not only are all positive numbers considered logically 'true', all negative numbers are also considered logically 'true'.

a = 3 ' true
b = -3 ' also true
IF a + b THEN ...  ' Logical OR intended

So 'true' OR 'true' evaluates to 'false'... um, no, that is not what we intended!

This is a very obvious example where a and b are directly assigned, but in a real program the evaluation of a & b would generally be something reasonably complex.

Oh, and I do quite like the syntax that JohnS suggested, and writing is as Bowden_P has done makes it pretty dang clear what is going on...
IF condition1 THEN
 IF condition2 THEN
   statement
Edited 2020-11-22 14:30 by MustardMan
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025