查找设置位并使用32位将它们移到最左侧位置

时间:2015-02-13 05:52:23

标签: c hex bit-manipulation

我试图弄清楚如何找到十六进制数中的所有设置位,然后使用32位表示法将这些位移到最左边的位置。

我的程序从命令提示符读取args,然后调用相应的函数并将第3个或第3个和第4个args传递给所选函数。

到目前为止,这是我的代码:

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

void printBits(unsigned long num){
    //Function to display a hexidecimal number in binary
    //Precondition: num is in hex notation
    //Postcondition: num is displayed in binary notation
    int i;
    int count = 1;
    unsigned long mask = 0x80000000;
    for (i = 1; i <=32; i++){
        int out = num & mask;
        num = num << 1;
        if (out ==0){
            printf("%u",0);
        }
        else{
            printf("%u",1);
        }
        if (count ==4){
            printf(" ");
            count = 0;
        }
        count++;
    }
    printf("\n");
}

void setUnion(unsigned long a, unsigned long b){
    //Function to display the union of 2 hexidecimal numbers
    //Precondition: a and b are both hexidecimal numbers
    //Postcondition: a is OR'd with b and the appropriate solution is displayed
    printBits(a|b);
}

void setIntersection(unsigned long a, unsigned long b){
    //Function to determine the intersection of two hexidecimal numbers
    //Precondition: a and b are both in hex format
    //Postcondition: a and b are compared using the & operator and the appropriate solution is displayed
    printBits(a&b);
}

void setComplement(unsigned long a){
    //Function to find the one's compliment of a give hex
    //Precondition: a is a hexidecimal number
    //Postcondition: the complement of a is displayed
    printBits(~a);
}

void countSet(unsigned long a){
    //Function to count the number of set bits in a
    //Precondition: a is a hexidecimal number
    //Postcondition: number of set bits are counted and count is displayed to user
    unsigned int count; // count accumulates the total bits set in a
    for (count = 0; a; count++){
        a &= a - 1; // clear the least significant bit set
    }
    printBits(a);
    printf("Number of bits set is ");
    printf("%i",count);
}

void setRotate(unsigned long x, unsigned long y){
    //Function to perform a rotation of bits to the right
    //Precondition: x is in hex form and will be rotated by y places to the right
    //Postcondition: x is displayed with bits rotated y positions to the right
    unsigned long num;
    num = (x >> y)|(x << (32 - y));//code obtained from geeksforgeeks.com, author unknown, date of publishing unknown
    printBits(num);
}

void shiftSet(unsigned long x){
    //Function to shift all set bits to the left
    //Precondition: x is a hexidecimal number
    //Postcondition: all set bits in x are shifted to the left most bit placements

    unsigned int count;
    for (count = 0; x; count++){
        x &= x - 1; // clear the least significant bit set
    }

    printBits((1 << (count % 32))+1);
}

int main(int argc, char *argv[]) {
    unsigned long x;
    unsigned long y;
    char invoke_command[] = ("lab2");
    if (argc != 3 && argc != 4){
        printf("Arguments incorrect, please provide 3 or 4 arguments");
        printf("\n");
        exit(0);
    }
    else {
        sscanf(argv[2], "%x", &x);

        switch(argv[1][1]){

            case 'p':
                printBits(x);
                break;
            case 'u':
                sscanf(argv[3], "%x", &y);
                setUnion(x,y);
                break;
            case 'i':
                sscanf(argv[3], "%x", &y);
                setIntersection(x,y);
                break;
            case 'c':
                setComplement(x);
                break;
            case 'r':
                sscanf(argv[3], "%i", &y);
                setRotate(x,y);
                break;
            case 's':
                countSet(x);
                break;
            case 'm':
                shiftSet(x);
                break;
        }
    }
    return 0;
}

我是C的新手,对位操作员不是很擅长。我的shiftSet功能是我遇到的困难。目前它正在将所有设置位向右移动,我无法弄清楚如何让它向左移动。如果有人可以提出任何建议,我将不胜感激。这也是我在这里的第一篇文章,所以我搞砸了我道歉的首选格式。

基本上我要找的是:传递0x55(0000 .... 0101 0101)然后得到 (1111 0000 ..... 0000)。

这是一个硬件问题,我确实和我的教授谈过这个问题,让我们说他的建议不是很有帮助。

2 个答案:

答案 0 :(得分:1)

第一个问题是count % 32。这将把0和32视为基本相同。您需要将移位值限制为0到31之间的数字,以避免未定义的行为。但是你不能把0和32视为同一个东西,所以其中一个需要作为一个特例来处理。

另一个问题是(1 << n) + 1。这将设置最多2位。我建议从0xffffffff开始,然后看看你是否可以弄清楚如何改变它以便你得出正确的答案。

顺便说一下,我测试了你计算位数的方法,看起来很有效,干得好!

答案 1 :(得分:1)

怎么样:

void shiftSet(unsigned long x){
    //Function to shift all set bits to the left
    //Precondition: x is a hexidecimal number
    //Postcondition: all set bits in x are shifted to the left most bit placements

    unsigned int count;
    for (count = 0; x; count++)
        x &= x - 1; // clear the least significant bit set

    unsigned long u = ~0UL;
    if (count == 0)
        u = 0;
    else if (count < 32)
        u = (u >> (32 - count)) << (32 - count);

    printBits(u);
}

能够使用函数来计算位数会很好,但是countBits()函数与I / O密不可分,并且不返回值,因此无法重用