使用位操作测试整数是否为大写ASCII字母

use*_*844 -1 c

对于赋值,我正在尝试在C中创建一些仅使用位操作来测试整数是否为ASCII大写字母的代码.该字母将由整数形式的ASCII代码给出,意思是0x41 <= ourint <= 0x5A.在做了一些研究后,我了解到小写字母和大写字母之间的区别是单词二进制版本的第六位数.大写有一个1和更低的有一个0.

我几乎拥有它,但我的代码不起作用.

到目前为止我所拥有的是什么

!(((x>>6)<<31) & 0)
Run Code Online (Sandbox Code Playgroud)

它的作用是将代码移动到右边6以获得第六个数字作为第一个数字,然后向右移动31以使其全部为0或1然后是31 0.我必须这样做,如果它是大写的,它返回1,所以我使用感叹号.

编辑:我的新代码是

!((~(((x & 32)>>5))<<31))>>31)
Run Code Online (Sandbox Code Playgroud)

但现在我仍然坚持测试的问题 0x7fffffff

chq*_*lie 5

您可以c通过检查其0x20位来测试ASCII字母是否0为大写,它必须是大写和1小写:

if (!(c & 0x20))
    printf("ASCII letter %c is uppercase\n", c);
Run Code Online (Sandbox Code Playgroud)

但请注意,如果您不知道这c是一封信,那么此测试不起作用.它会错误地匹配'@''[','\\',']','^''_',并与高位设置为192〜223个字符,这是不ASCII的一部分,但有效的全范围unsigned char值.

如果您希望单个测试验证是否c为大写ASCII字母,请尝试:

if ((unsigned)(c - 'A') <= (unsigned)('Z' - 'A'))
     printf("%c is an uppercase ASCII letter\n", c);
Run Code Online (Sandbox Code Playgroud)

编辑:不清楚你的意思我不被允许使用if语句或任何类型的类型转换操作.我必须测试这个数字是否在两个数字之间,包括远远超出ASCII代码范围的数字,如果是,则返回1,否则为0.

  • 如果你知道c是一个字母,都!(c & 0x20)(((c >> 5) & 1) ^ 1)有一定的价值1,如果c是大写字母,0如果没有.
  • 如果c可以是任何整数值,只需编写常规比较(c >= 'A' && c <= 'Z'),编译器将产生比尝试危险的比特诡计更好的代码.

再次编辑:

因为c可以是任何整数值,并且只允许位操作,这是另一种解决方案:!((c >> 5) ^ 2) & (0x07fffffeU >> (c & 31)).下面是一个测试这个的程序:

#include <stdio.h>
#include <stdlib.h>

static int uppertest(int c) {
    return !((c >> 5) ^ 2) & (0x07fffffeU >> (c & 31));
}

int main(int argc, char *argv[]) {
    for (int i = 1; i < argc; i++) {
        int c = strtol(argv[i], NULL, 0);
        printf("uppertest(%d) -> %d\n", c, uppertest(c));
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)