使用((c1 ^ c2)& ~32)来测试c1和c2在不同情况下是否是相同的字符

时间:2015-06-24 05:33:39

标签: c operators

我看到了一些这样的代码

if( ((c1^c2) & ~32)==0 )
{
  ...
}

在此代码段中,代码可能意味着如果if语句为真,那么c1c2在不同情况下是相同的字符,意思是其中一个是+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 个答案:

答案 0 :(得分:4)

(c1^c2) & ~32) xors c1c2,结果包含两个字符中的位和& ~32清除(忽略)位5 (两者是否相同都归零)。将此与零进行比较,检查bit 5以外的所有位是否相同。

如果你确定至少c1c2是一个有效的拉丁字符(az,AZ),这可用于检查2个字母是否相等,忽略了ascii表示中的情况。

要理解这一点,让我们挑选两个不同大小写的字符并进行比较:

       +---+---+---+---+---+---+---+---+
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 / s Jt v / s z尝试相同的操作。 所以没有魔法,只有这种逻辑。

有时这种情况也写成:

if (ch1 == ch2 || (ch1 ^ 32) == ch2)
{
  ...
}