QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: davidshq on November 03, 2018, 12:05:45 pm

Title: Is There a ! Option?
Post by: davidshq on November 03, 2018, 12:05:45 pm
Hi Folks,

Does QB64 have any operators that allow negating an expression? I'm not sure I'm saying that right...what I mean is, a way to write:

Code: QB64: [Select]
  1. IF !(_DIREXISTS("C:\mydir")) THEN
  2.   ' DO Something

Its fairly easy to get around this, I'm using:

Code: QB64: [Select]
  1. IF _DIREXISTS("C:\mydir") = FALSE THEN
  2.   ' DO Something

Alternatively one could do:

Code: QB64: [Select]
  1. IF _DIREXISTS("C:\mydir") THEN
  2.    ' DO Something

But that feels quite inelegant to me.
Title: Re: Is There a ! Option?
Post by: bplus on November 03, 2018, 12:20:03 pm
NOT not working?

NOT NOT

Who's there?

Code: QB64: [Select]
  1. IF NOT _DIREXISTS("C:\mydir") THEN
  2.     PRINT "I already knew that, C:\mydir, does not exist."
  3.  

Not mydir!
Title: Re: Is There a ! Option?
Post by: davidshq on November 03, 2018, 12:57:40 pm
Ugg. You know, I can do some pretty advanced things...its the really simple, "hey, i'm n00b" stuff that trips me up!
Title: Re: Is There a ! Option?
Post by: bplus on November 03, 2018, 01:10:40 pm
Yeah, I think I wrote code without a single blunder, once. ;-))
Title: Re: Is There a ! Option?
Post by: TerryRitchie on November 03, 2018, 01:44:39 pm
Ugg. You know, I can do some pretty advanced things...its the really simple, "hey, i'm n00b" stuff that trips me up!

Welcome to the club. I'll be coding along feeling like the coding wizard that I am then BAM! Three hours later after tracking a bug I know MUST be a bug in QB64's compiler I find a misplaced comma ... doh!
Title: Re: Is There a ! Option?
Post by: Pete on November 03, 2018, 02:05:38 pm
I've always used:

Code: QB64: [Select]
  1. IF _DIREXISTS("C:\mydir") THEN
  2.    ' DO Something
  3.  

I think I tried NOT once, to see if it was an alternative but if I recall correctly, NOT did NOT work!

Maybe Steve can make us a: _DIRAINTTHERE

Pete
Title: Re: Is There a ! Option?
Post by: OldMoses on November 11, 2018, 04:27:26 pm
NOT not working?

NOT NOT

Who's there?

That was amusing enough to code. ;)
Imagine my amusement when it worked...

Code: QB64: [Select]
  1. PRINT "input a number ";
  2. IF NOT NOT a% = 1 THEN
  3.     PRINT "a is one"
  4.     PRINT "a isn't one"
  5.  

No, no, no, no, no, I think maybe I've just discovered the Jim Trott school of coding....
Title: Re: Is There a ! Option?
Post by: luke on November 12, 2018, 05:22:07 am
Horrible jokes aside, there is an annoying subtlety that plagues QB64 (and many other BASIC's I suppose). Something like this behaves as expected:
Code: QB64: [Select]
  1. If Not 2 > 3 Then Print "2 is not > 3"
And here's an easy way to do something only if a substring is present:
Code: QB64: [Select]
  1. If Instr("abc", "a") Then Print "Abcd"
But don't try and be clever and negate that:
Code: QB64: [Select]
  1. If Not Instr("abc", "a") Then Print "Huh?"
Unlike C/Python/Most other things I can think of, QB64's NOT is strictly a bitwise negation. So above Instr("abc", "a") evaluates to 1, and NOT 1 is -2 (why? because two's complement (https://en.wikipedia.org/wiki/Two%27s_complement)). This is likely what Pete is remembering above; a correct way to write this check is to do
Code: QB64: [Select]
  1. If Instr("abc", "a") Then
  2.     Print "That's better"
Though personally I prefer
Code: QB64: [Select]
  1. If Instr("abc", "a") = 0 Then ...

A similar caveat applies to all the bitwise-masquerading-as-logical-operators, AND OR XOR IMP EQV (If you've never seen the last two, today's your lucky day!). Try predicting what these two lines will output:
Code: QB64: [Select]
  1. If Instr("abc", "a") And Instr("abc", "b") Then Print "X"
  2. If Instr("abc", "a") And Instr("abc", "c") Then Print "Y"
  3.  

EDIT:
To get more sensible behaviours, you can do a kind of typecast to Boolean like so:
Code: QB64: [Select]
  1. DEFLNG A-Z
  2. CONST FALSE = 0, TRUE = NOT FALSE
  3.  
  4. '     True,     True,     False,   True,    False
  5. PRINT bool(-2); bool(-1); bool(0); bool(1); bool(2)
  6. '     False,        True,        False
  7. PRINT NOT bool(-1); NOT bool(0); NOT bool(1)
  8.  
  9. FUNCTION bool (a)
  10.     IF a = 0 THEN bool = FALSE ELSE bool = TRUE
  11.  
Title: Re: Is There a ! Option?
Post by: Pete on November 12, 2018, 06:18:56 am
Yep. And now back to our regularly scheduled programs...
Title: Re: Is There a ! Option?
Post by: SMcNeill on November 12, 2018, 08:50:50 am
I've never really found NOT to be that confusing.  Folks just need to think of it as another mathematical function, and not a logic function.

Before I ever really knew the process of WHY NOT was doing what it did, I played around with it and saw WHAT it was doing.

NOT 0?   -1
NOT 1?   -2
NOT 2?   -3

Printing the results in a small loop, I realized, "Hey!  All NOT does is Add One and then Negate the result.   (It actually flips bits, but when I first was learning BASIC back in the 80s, I had no clue what a bit was, but I could still understand the mathematical operation of "add one, negate".)

Since I always thought of NOT as a math function, instead of a logic function, I never fell into the trap some others have with it.

INSTR returns a value of 0 to wherever the character is in a string.  You'll NEVER be able to NOT it and have a value of 0 -- or even a positive value!  The result will *ALWAYS* be less than 0.

INSTR and search string doesn't exist?  Result is 0.  NOT 0 is -1.
INSTR and search string is in the first position?   Result is 1.  NOT 1 is -2.
Search string found in the Nth position?  Result is (N + 1), negated... 

And, since BASIC considers any value <> 0 to be TRUE, then *ALL* cases of NOT INSTR are going to be TRUE.

If folks want a logic not, then they should write a quick function for it, instead of trying to use a mathematical one.

FUNCTION LNot (value)
   IF value = 0 THEN LNot = -1 ELSE LNot = 0
END FUNCTION

Then you can use it as Luke and Pete described.

IF LNOT(INSTR(a$, search$) THEN....

So now we get a TRUE/FALSE result for if there's search$ in a$, rather than adding one to a positional result and then negating the answer.

************************

If people want to use NOT, AND, OR, and such as logic operators, they should first convert the things they're comparing into logic values.

FUNCTION C2L (value) 'Convert 2 Logic
   IF value = 0 then C2L = 0 ELSE C2L = -1
END FUNCTION

4 AND 3 = 0   -----  FALSE
C2L(4) AND C2L(3) = -1     ----   TRUE

Most results aren't 0 or -1, so they're NOT going to be suitable for logic operations.  Convert them first, and you're good to go -- just like you may need to use VAL to convert a string or STR$ to convert a number, before you can use them as you want.
Title: Re: Is There a ! Option?
Post by: bplus on November 12, 2018, 09:01:40 am
<content removed>

From what I gathered, Jim Trott suffered from dementia perhaps after a bout of Boolean fever.

Luke's presentation reminded me of the run around  I had with .5
Code: QB64: [Select]
  1. WHILE NOT escape
  2.     IF .5 THEN PRINT ".5 is true."
  3.     IF NOT .5 THEN PRINT "NOT .5 is true."
  4.     _LIMIT 1

Yeah, I have to say the cure for Boolean fever is to compare directly to 0 when using IF.
Code: QB64: [Select]
  1. WHILE NOT escape
  2.     IF .5 <> 0 THEN PRINT ".5 is true."
  3.     IF NOT .5 <> 0 THEN PRINT "NOT .5 is true."
  4.     _LIMIT 1
  5.  
Title: Re: Is There a ! Option?
Post by: OldMoses on November 12, 2018, 07:02:57 pm
From what I gathered, Jim Trott suffered from dementia perhaps after a bout of Boolean fever.

No, noooo, no, he was WENDlessly DO LOOPY