используйте ((c1^c2) & ~32), чтобы проверить, являются ли c1 и c2 одним и тем же символом в разных случаях
Я видел такой код
if( ((c1^c2) & ~32)==0 )
{
...
}
В этом фрагменте кода, вероятно, означает, что если утверждение if
истинно, то c1
и c2
являются одним и тем же символом в разных случаях, что означает, что один из них находится на расстоянии +32 или -32 от другого. Почему это так?
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
Почему это? что же в этом волшебного?
1 ответ:
(c1^c2) & ~32)
xorsc1
иc2
, результат содержит биты, которые находятся в обоих символах и&
с~32
очищает (игнорирует) бит 5. (Он обнуляется независимо от того, был ли он одинаковым в обоих случаях или нет). Сравнивая это с нулем, проверяет, все ли биты, отличные отbit 5
, одинаковы.Это можно использовать, чтобы проверить, равны ли 2 буквы, игнорируя их регистр в представлении ascii, если вы уверены, что по крайней мере
c1
илиc2
является допустимым латинским символом(a-z, A-Z).Чтобы понять это, давайте выберите 2 символа с разным регистром и сравните их:
+---+---+---+---+---+---+---+---+ 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 | +---+---+---+---+---+---+---+---+
Вы можете попробовать то же самое с
j
v/sJ
илиt
v/sz
. Поэтому здесь нет никакой магии, только эта логика.Иногда это условие также записывается как:
if (ch1 == ch2 || (ch1 ^ 32) == ch2) { ... }