找到设置位并使用 32 位将它们移到最左边的位置

Find set bits and shift them to left most position using 32 bits

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

我的程序从命令提示符中读取参数,然后调用适当的函数并将第三个或第三个和第四个参数传递给所选函数。

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

#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 功能是我遇到的困难。目前它正在将所有设置位向右移动,我不知道如何让它向左移动。如果有人可以提供任何建议,我将不胜感激。这也是我第一次 post 在这里,所以我搞砸了我道歉的首选格式。

基本上我正在寻找的是:传入 0x55 (0000....0101 0101) 并获得 (1111 0000.......0000)。

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

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

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

顺便说一句,我测试了你计算位数的方法,似乎有效,干得好!

怎么样:

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 密不可分,并且没有 return 一个值, 所以不能重复使用。