Use ((c1 ^ c2) & ~ 32) to check if c1 and c2 are the same characters in different cases
I have seen code like this
if( ((c1^c2) & ~32)==0 )
{
...
}
In this snippet, the code probably means that if the operator if
evaluates to true, then c1
they c2
are the same symbol in the other case , which means that one of them is + 32 or -32 from the other. Why is this?
I tested myself and found that in some cases this is true and in others it is not:
printf("%d", (65^97)& ~32); //output is 0. right
printf("%d", (97^65)& ~32); //output is 0. right
printf("%d", (50^82)& ~32); //output is 64!! not the same though 82-50=32
Why? What's the magic in it?
source to share
(c1^c2) & ~32)
xors c1
and c2
, the result contains the bits that are in both characters, and &
with ~32
clears (ignores) bit 5. (It clears whether it was the same in both or not). Comparing this to zero, checks if all bits other than bit 5
.
This can be used to check if 2 letters are equal, ignoring their case in ascii representation if you are sure that atleast c1
or c2
is a valid latin character (az, AZ).
To understand this, let's pick two characters with a different case and compare them:
+---+---+---+---+---+---+---+---+
a | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
+---+---+---+---+---+---+---+---+
| x | | | | | |
+---+---+---+---+---+---+---+---+
A | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
a ^ A | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
32 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
~32 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
& | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+
You can try the same with j
v / s j
or t
v / s z
. So no magic is involved, just this logic.
Sometimes this condition is also written as:
if (ch1 == ch2 || (ch1 ^ 32) == ch2)
{
...
}
source to share