Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的位旋转_C_Bit Manipulation - Fatal编程技术网

C语言中的位旋转

C语言中的位旋转,c,bit-manipulation,C,Bit Manipulation,问题:C编程语言练习2-8,“编写一个函数rightrot(x,n),返回整数x的值,向右旋转n个位置。” 我已经尽我所能做到了这一点。这就是我面临的问题。为这个练习取一个给定的数字,比如说29,然后将其向右旋转一个位置。 11101变为11110或11130。让我们假设我们正在处理的系统的无符号整数类型大小为32位。让我们进一步假设数字29存储在无符号整数变量中。在内存中,数字前面将有27个零。所以,当我们使用我下面发布的几种算法中的一种将29向右旋转时,我们得到的是2147483662。这显

问题:C编程语言练习2-8,“编写一个函数rightrot(x,n),返回整数x的值,向右旋转n个位置。”

我已经尽我所能做到了这一点。这就是我面临的问题。为这个练习取一个给定的数字,比如说29,然后将其向右旋转一个位置。
11101变为11110或11130。让我们假设我们正在处理的系统的无符号整数类型大小为32位。让我们进一步假设数字29存储在无符号整数变量中。在内存中,数字前面将有27个零。所以,当我们使用我下面发布的几种算法中的一种将29向右旋转时,我们得到的是2147483662。这显然不是期望的结果

unsigned int rightrot(unsigned x, int n) {
    return (x >> n) | (x << (sizeof(x) * CHAR_BIT) - n);
}
unsigned int rightrot(unsigned x,int n){
返回(x>>n)|(x>1;
x |=(rbit>=1;

x |=(rbit您可以使用二进制搜索在32位值中找到第一个“1”的位置。然后注意LSB位置中的位,将该值右移所需的位数,并将LSB位置于第一个“1”的位置。

按位旋转总是必须在给定宽度的整数内。在这种情况下,如果您假设是32位整数,2147483662(
0b10000000000000001110
)确实是正确答案;您没有做错任何事情

根据任何合理的定义,
0b11110
都不会被视为正确的结果,因为继续使用相同的定义将其向右旋转将永远不会返回原始输入。(考虑到另一次向右旋转将产生
0b1111
,继续旋转将不会产生任何效果。)

int bitcount(无符号x){
int b;
对于(b=0;x;b++)
x&=x-1;
返回b;
}
无符号rightrot(无符号x,整数n){
int b=位计数(x);

无符号a=(x&(~0在我看来,本书中紧接着本练习之前的章节的精神是让读者在不知道整数大小(以位为单位)或任何其他类型的情况下解决这个问题。本节中的示例不需要这些信息;我认为练习也不应该

不管我怎么认为,这本书还没有在第2.9节中引入sizeof运算符,因此计算类型大小的唯一方法是“手工”计算位

但是我们不需要费心去做这些,我们可以在n个步骤中进行位旋转,不管数据类型中有多少位,每次旋转一位

仅使用第2.9节之前本书所涵盖的语言部分,下面是我的实现(使用整数参数,返回一个整数,如练习所指定):循环n次,每次迭代x>>1;如果x的旧低位为1,则设置新的高位

int rightrot(int x, int n) {
    int lowbit;

    while (n-- > 0) {
        lowbit = x & 1;            /* save low bit */
        x = (x >> 1) & (~0u >> 1); /* shift right by one, and clear the high bit (in case of sign extension) */
        if (lowbit)
            x = x | ~(~0u >> 1);   /* set the high bit if the low bit was set */
    }

    return x;
}

我曾想过使用binsearch,但这本书声称,这些练习可以使用练习前提供给你的信息来回答。作者直到本书后面才讨论排序/搜索的细节。我同意@Dashwuff的观点;你不应该这样做。我认为这意味着fir的行为前两个例子是正确的,我没有发疯。我不确定你的假设2147483662是错误的答案。在我看来这是对的!问题说的是“整数x”,这意味着x中有一定数量的位,例如32。否则,应该是rightrot(1,1)总是返回1?李斯特先生,我完全承认。显然,我对binay的一些概念,它的存储方式,以及它的解释方式都是错误的。我首先假设这个值是错误的,因为我在内存中使用的27个零对我来说没有意义这个值。我确实明白你对一的看法。如果rightrot(1,1)总是返回1那么一个人怎么能向左旋转像1000或100000000000000000这样的数字。注意到你的字号函数中的错误。它应该是返回b,而不是返回x;我花了将近十个小时才屈服并寻求帮助。我以为我已经失去了理智,但我确实学会了,至少现在我知道我的理智和能力做简单的数学都是完整的。谢谢。我当然可以看到问题。例如,问题没有提到整数是16位还是32位,这是一个非常重要的区别:结果会不同。有符号整数也是一样:分解奇数会产生负结果。所以很好地想知道关于这一点,不要简单地编写例程而不考虑结果。例如,如果我们想将10101011旋转3位以获得01110101,那么我们只需执行01100000 | 0000101。要获得01100000,我们执行(x&~(0
int bitcount(unsigned x) {
    int b;
    for(b = 0; x; b++)
        x &= x-1;
    return b;
}

unsigned int rightrot(unsigned x, int n) {
    unsigned rbit;
    int shift = bitcount(x);
    while(n--) {
        rbit = x & 1;
        x >>= 1;
        x |= (rbit << shift);
    }
}
int bitcount(unsigned x) {
    int b;
    for(b = 0; x; b++)
        x &= x-1;
    return b;
}

unsigned rightrot(unsigned x,int n) {
   int b = bitcount(x);
   unsigned a = (x&~(~0<<n))<<(b-n+1);
   x>> = n;
   x| = a;
}
int rightrot(int x, int n) {
    int lowbit;

    while (n-- > 0) {
        lowbit = x & 1;            /* save low bit */
        x = (x >> 1) & (~0u >> 1); /* shift right by one, and clear the high bit (in case of sign extension) */
        if (lowbit)
            x = x | ~(~0u >> 1);   /* set the high bit if the low bit was set */
    }

    return x;
}