DAY 019: EQV
#1
Just like IMP, this is one of those keywords that does binary comparisons on values, that you never see anyone using.  

WHY?

Because everyone seems to be under a misconception about what EQV actually does!

From our wiki page -- EQV - QB64 Phoenix Edition Wiki -- we learn that this does bitwise comparisons.  When both bits are the same (both are 0, or both are 1), then EQV reports that it's TRUE, they're equivalent to each other.  If the two bits are different, EQV reports to us that it's FALSE, and they're not equivalent to each other.

Most people see that, or read that, and think, "Hey!  That's simple enough.  If they're the same, it's true.  If they're different, it's false.  This is just like equals!"

BZZZZZTTTTZZZ!!  That's completely WRONG!

And let me tell you why:

0 EQV 0 = 1
1 EQV 1 = 1
0 EQV 1 = 0
1 EQV 0 = 0

^ Those are the basic rules of evaluating our bits.   Now, let's apply it to two real world numbers!

4 = &B00000100
2 = &B00000010 
EQV ----------
    &B11111001

All those 0's that compare to 0's become 1.  All the 1's that compare to 1's become 1.  When a 0 compares to a 1, the result is 0.  <<-- All just like the rules for EQV tell us.

Now, is 2 EQUAL TO 4??   (2 = 4)??

Of course not!!

But is 2 EQV 4?? 

Absolutely!  It's 249!  (Just count and add the bits in the result above... 11111001 = 249.)

Remember, in BASIC, *ONLY* zero is FALSE.  Anything else is TRUE.

2 is not equal to 4, but it *is* EQV to 4.



Now, I know what some of you guys are going to say, after you think on this for a bit:  "Then in BASIC, EQV is just about useless as all mixed numbers are going to give TRUE results."

1 EQV 0 = TRUE
1 EQV 1 = TRUE
1 EQV 2 = TRUE
1 EQV 3 = TRUE  

Try it for yourself: 
Code: (Select All)
Dim As _Unsigned _Byte a, b, c
    a = 1
For i = 0 To 10
    b = i
    c = a Eqv b
    Print c
Next


11 non-zero numbers on the screen..  11 TRUE values!  They're *ALL* True!!

"Now hold on one moment there, Stevey-boy!"  (I'm channeling my inner Pete here, as I can hear him already.)  "Just how the hell did 1 and 0 end up being TRUE?  By our definition from the wiki, they have to be FALSE!!  Somethings fishy here, and it isn't the tuna I had for supper last night!"

BZZZZZZZZTTTZZZZ!!  Sorry, Imaginary @Pete.  The result is exactly what you'd expect to see, if you think about it for just a moment.

What is 1?  What is 0??

1 = &B00000001
0 = &B00000000

Now, that 0 and 1 might EQV out to become 0, but what happens to all those 0's and 0's when they're compared against each other??

11111110.

1 AND 0 = 254 (as unsigned bytes).   It's definitely true!

"Then how the hell do you ever generate a FALSE with EQV?  That's impossible, for tarnation's sake!"

BZZZZZZZZTTTZZZZ!!  Sorry again, Imaginary @Pete.

You get FALSE back, if -- and only if -- EVERY bit is the opposite of the other!

 &B10101010
 &B01010101
EQV========
 &B00000000  

 &B11111111
 &B00000000
EQV========
 &B00000000

 &B00000001
 &B11111110
EQV========
 &B00000000




When EVERY bit is the opposite of the other, the result is FALSE.  Otherwise it's TRUE.


So 1 EQV 254 is FALSE. 0 EQV 255 is FALSE. 127 EQV 128 is FALSE.

.
.
.

"Ha!  Ha!  You're a goober!  That's wrong!  I just tried it!  Nanner!  Nanner!"

Shut up, Imaginary @Pete!  

It's only wrong because you didn't pay attention to what I just stressed in bold, italic, underline above!

When EVERY bit is the opposite of the other, the result is FALSE.  Otherwise it's TRUE.

What variable type did you use, when you tested those values for 1 EQV 254?  0 EQV 255?

"Umm...  Whatever QB64-PE defaults to.  I just typed them in as numbers!"

Then let me ask..  What is 254 as an INTEGER value?  What is 1 as an INTEGER value??

254 = &B0000000011111110
   1 = &B0000000000000001

See the problem already?  There's a whole bunch of leading 0's which match for both values!

It's only when one is dealing with BYTE values, that 1 EQV 254 is FALSE.  If they're a different variable type, they're both padded with zeros which are going to match up, and 0 EQV 0 = 1...

When EVERY bit is the opposite of the other, the result is FALSE.  Otherwise it's TRUE. 



I can't stress the above enough.  EQV is not a form of equal.  It's a bitwise comparison, and...



When EVERY bit is the opposite of the other, the result is FALSE.  Otherwise it's TRUE. 
Reply
#2
I do Aikido. I'm into flipping people, not bits. Speaking of "flipping" people...  Imaginary @Admin.

Probably the most important part to take away from this post is auto messaging is messing up again. Big Grin

Other than that, I can't recall reading a single program post, which utilized this keyword. I suppose it might be interesting to see what types of applications bit flipping is good for, other than maybe taking a different approach to a coding a string math routine. So in the absence of use and examples, it's pretty hard to see if this is could be a useful tool OR NOT. 

Pete
Reply
#3
(11-25-2022, 05:59 PM)SMcNeill Wrote: Just like IMP, this is one of those keywords that does binary comparisons on values, that you never see anyone using.  
This keyword is worthless considering it's the opposite of XOR. Just test for something that is false with "XOR" instead of the main tendency of testing for it to be true with "EQV". I have never used the latter keyword in my programs.
Reply
#4
I agree with you Steve, it's hard to imagine a math formula which works with 2 being the equivalent of 4. And like IMP, I want to be able to force the relationship between EQV and or IMP. For example

A$ = "10 Apples"
B$ = "5 Oranges"

A$ IS EQV of B$

or

RaceCar$ Does IMP "Fast Driver"
SlowCar$ Does IMP "Retired Driver"

Seems to me we need a NON Bit Logic for EQV and IMP. The other Boolean operators work fine with my math formulas. I can understand the results I get much better.
Reply
#5
@SMcNeill
sorry for my position aside.
In BASIC there are Logical operators or only Bitwise operators?

Playing with the binary version of a number it is all straight and right...
but there is the logic that not is only bits and bytes...
we can agree that it is orrible that in BASIC there are no value for TRUE and FALSE as values not in the same field of numbers (it doesn't matter if the number is expressed in binary, octal, decimal or hexadecimal basis)...
there is just a little difference between  1 AND 256  versus False AND True.
The first expression (1 AND 256) is a bitwise operation and it has been showed at high level by Steve.
The second expression (False AND True) is a logical operation, in it is no important if you use binary/octal/decimal/hexadecimal  number or symbolic sign, all that is important is that the whole universe of possible values are True and False that are opposite.
Both if we express True = 0 and False <> 0 or True <>0 and False = 0 the table of truth in logic math is the same!
The bitwise logic follows the rules and the path showed by Steve.
The logical math follows the rules and the path of its field.

Here some references out of my IMHO:
https://en.wikipedia.org/wiki/Truth_table
https://en.wikipedia.org/wiki/Mathematical_logic


We pay the lackness of the logic type in BASIC. But we must not loose our mind in this misunderstandment confounding Bitwise and Logic operators. 

We surrogate True and False with 2 variables or CONSTants giving False = 0 and True = not False, but our BASIC language returns us a -1 when it wants meaning True.
It is clear that this condition makes more confusion... we would expect that all that is not -1 is no true and all that is not 0 is no false.
In this situation our BASIC leave us in trouble. But if we love BASIC, we love it with all its defects! And not to hide its defects!

So we must pay more attention when we declare the substitutes of False and True to make logic conditions in choice operators!
Try to run my example test in the original EQV thread... you can see an unwilling result in the output... AND returns True only if both conditions are True, and clearly with its first parameter False (0) we get a True response... there is something bitwise and not logic in that behaviour!


Thanks for reading, talking and sharing.
Reply
#6
If one wants logical operations, then they need to end up writing their own.

Code: (Select All)
Print 1 And 2
Print LogicalAND(1, 2)
Print 1 Or 2
Print LogicalOR(1, 2)





Function LogicalAND (num1, num2) 'if they're both true, then the result is true
    If num1 <> 0 And num2 <> 0 Then LogicalAND = -1
End Function

Function LogicalOR (num1, num2) 'if either is true, then the result is true
    'Note that this one isn't much different from a plain OR statement, except it keeps our result as a logical value of -1
    If num1 <> 0 Or num2 <> 0 Then LogicalOR = -1
End Function


I'm not certain what logical operators someone might want/need, but that's basically logical AND and OR.  They're simple enough for folks to implement on their own, rather than using bitwise operators, if that's what they're wanting.  Wink
Reply




Users browsing this thread: 3 Guest(s)