检查第n位是否设置为字节的函数

时间:2012-01-19 03:58:31

标签: c bit-manipulation

我想要一个简单的C函数,如果一个字节中的第n位设置为1,它将返回true。否则它将返回false。

这在执行时间方面是一个关键功能,所以我想到了最佳的方法。

7 个答案:

答案 0 :(得分:36)

以下功能可以满足您的需求:

int isNthBitSet (unsigned char c, int n) {
    static unsigned char mask[] = {128, 64, 32, 16, 8, 4, 2, 1};
    return ((c & mask[n]) != 0);
}

这假定为8位字节(不是C中给出的),第0位是最高位的。如果这些假设不正确,则只需要扩展和/或重新排序mask数组。

由于您将速度视为最重要的考虑因素,因此未进行任何错误检查。 传递无效的n,这将是未定义的行为。

在疯狂的优化级别-O3,gcc告诉我们:

isNthBitSet:    pushl   %ebp
                movl    %esp, %ebp
                movl    12(%ebp), %eax
                movzbl  8(%ebp), %edx
                popl    %ebp
                testb   %dl, mask(%eax)
                setne   %al
                movzbl  %al, %eax
                ret
mask:           .byte   -128, 64, 32, 16, 8, 4, 2, 1

这是非常小而有效的。如果你将它设置为静态并建议内联,或强制它内联为宏定义,你甚至可以绕过函数调用的成本。

请确保您对您提供的任何解决方案进行基准测试,包括(a)。优化中的头号口号是“测量,不要猜测!”

如果您想知道按位运算符的工作方式,请参阅here。简化的AND-only版本如下。

只有在tewo源中设置了两个位时,AND操作&才会在目标中设置一个位。相关表格是:

AND | 0 1
----+----
 0  | 0 0
 1  | 0 1

对于给定的char值,我们使用单比特位掩码来检查是否设置了一个位。假设你有值13,你想看看是否设置了第三个从最低位开始的位。

Decimal  Binary
  13     0000 1101
   4     0000 0100 (the bitmask for the third-from-least bit).
         =========
         0000 0100 (the result of the AND operation).

您可以看到掩码中的所有零位导致等效结果位为零。掩码中的单个位基本上会让值中的等效位流入结果。如果我们检查的位为零,则结果为零;如果为1,则结果为非零。

这就是return语句中的表达式来自的地方。 mask查找表中的值都是单比特掩码:

Decimal  Binary
  128    1000 0000
   64    0100 0000
   32    0010 0000
   16    0001 0000
    8    0000 1000
    4    0000 0100
    2    0000 0010
    1    0000 0001

(a) 知道我有多好,但你没有: - )

答案 1 :(得分:25)

只需检查(1 << bit) & byte的值即可。如果它非零,则设置该位。

答案 2 :(得分:10)

让数字为num。然后:

return ((1 << n) & num);

答案 3 :(得分:4)

bool isSet(unsigned char b, unsigned char n) { return b & ( 1 << n); }

答案 4 :(得分:2)

#include<stdio.h>
int main()
{
   unsigned int n,a;
   printf("enter value for n\n");
   scanf("%u",&n);
   pintf("enter value for a:\n");
   scanf("%u",&a);
   a= a|(((~((unsigned)0))>>(sizeof(int)*8-1))<<n);
   printf("%u\n",a);
}   

答案 5 :(得分:2)

另一种方法是

    bool isNthBitSet (unsigned char c, int n) {
      return (1 & (c >> n));
    }

答案 6 :(得分:0)

 DataView view = new DataView(this.excelBook.Tables);
 DataTable distinctValues = view.ToTable(true, "DataSourceName");