在unsigned int中搜索位模式

时间:2018-03-18 19:29:47

标签: c bit-manipulation bitwise-operators bit bit-shift

我通过Kochan的C语言编程学习C.其中一个练习如下:

  

编写一个名为bitpat_search()的函数,用于查找unsigned int内指定的位模式的出现。该函数应该有三个参数,应该这样调用:

bitpat_search (source, pattern, n)

  

该函数从最左边的位开始搜索整数source,以查看pattern中最右边的n位是否出现在source中。如果找到模式,则让函数返回模式开始的位数,其中最左边的位为数字0.如果找不到模式,则使函数返回-1。所以,例如,电话

index = bitpat_search (0xe1f4, 0x5, 3);

  

导致bitpat_search()函数搜索数字0xe1f4(= 1110 0001 1111 0100二进制)以查找三位模式0x5(= 101二进制)的出现。该函数返回11以指示在source中以位号11开头找到该模式。

     

确保该函数不对int的大小做出假设。

这是我实现该功能的方式:

#include <stdio.h>

int bitpat_search(unsigned int source, unsigned int pattern, int n);
int int_size(void);

int main(void)
{
    printf("%i\n", bitpat_search(0xe1f4, 0x5, 3));

    return 0;
}

int bitpat_search(unsigned int source, unsigned int pattern, int n)
{
    int size = int_size();
    pattern <<= (size - n);
    unsigned int compare = source;

    int bitnum = 0;

    while (compare)
    {
        compare >>= (size - n);
        compare <<= (size - n);

        if (compare & pattern)
        {
            return bitnum;
        }
        else
        {
            source <<= 1;
            bitnum++;
            compare = source;
        }       
    }

    return -1;
}

// Calculates the size of an integer for a particular computer
int int_size(void)
{
    int count = 0;
    unsigned int x = ~0;

    while (x)
    {   
        ++count;
        x >>= 1;
    }

    printf("%i\n", count);

    return count;
}

首先,我计算一个整数的大小(不能使用sizeof())。然后,我调整我们正在寻找的模式,以便它从MSB开始。我创建了一个临时变量compare并为其赋值source,我还将变量bitnum初始化为0;它将跟踪我们正在比较的位的位置。

在循环内,我将compare向右和向左移动(在位与位模式比较的位的右侧和左侧添加0&#39;)然后我比较值:if是,返回位数,否则,源向左移动一次,然后分配给compare(这实际上将我们在compare中比较的位的位置向右移动) bitnum递增。如果在pattern中找不到source并且根据说明返回-1,则循环停止执行。

然而,我的节目输出结果是14,而不是11 ..我通过铅笔和纸张跟踪程序,并没有理解出了什么问题......帮助?

1 个答案:

答案 0 :(得分:4)

您的测试不正确:(compare & pattern)仅检查comparepattern是否至少有一个共同位。您应该使用掩码并写下if ((compare & mask) == pattern)

以下是更正后的版本:

int bitpat_search(unsigned int source, unsigned int pattern, int n) {
    int i, bitcount;
    unsigned int mask = (1U << n) - 1;

    pattern &= mask;   /* mask off the n rightmost bits */

    for (bitcount = 0; (source >> bitcount) != 0; bitcount++)
        continue;

    for (i = 0; i <= bitcount - n; i++) {
        if (((source >> (bitcount - n - i)) & mask) == pattern)
            return i;
    }
    return -1;  /* not found */
}