C按位圆移位 - 意外结果

问题描述 投票:2回答:1

我目前正在进行K&R C书籍练习,并参加第2章练习8。挑战在于编写一个“旋转”功能,将无符号整数x的位旋转(或循环移位)n位。我相信我已经提出了一个解决方案,但它没有回归我所期望的。给定数字213,即11010101二进制,向右旋转2位将产生01110101,这是117。然而,我的计划被给予x=213n=2返回53。我已经尝试在注释中写出二进制形式的整数正在发生的过程,并且找不到问题。任何帮助,将不胜感激。

#include <stdio.h>

unsigned rotright(unsigned x, int n)
{
    /* Example with x = 11010101 (213 in decimal), n = 2
        First iteration:
            x = (01101010) | ~(11111111 >> 1) = 11101010
        Second iteration:
            x = (01110101) | ~(11111111 >> 0) = 01110101
        Returns 01110101

    right shifts only if last bit of x == 1, then sets first bit of right shifted x to 1
    if last bit of x == 0, x is right shifted by 1 and then unchanged.

    (01101010) | ~(11111111 >> (11010101 & 00000001))
    = 01101010 | ~(11111111 >> 00000001)
    = 01101010 | 10000000 = 11101010

    (11101010) | ~(11111111 >> (11101010 & 00000001))
    = 01110101 | ~(11111111 >> 0)
    = 01110101 | 00000000 = 01110101
    */
    for (; n > 0; n--)
        x = (x >> 1) | ~(~0 >> (x & 1));
    return x;
}

int main()
{
    printf("%d\n", rotright(213, 2));
    return 0; 
}
c bit-manipulation bitwise-operators
1个回答
3
投票

x =(x >> 1)| 〜(~0 >>(x&1));

你得到53因为这是(213 >> 2)

~(~0 >> (x & 1))总是0,因为~0是-1,而(-1 >> n)在你的情况下再次为-1,最后〜(-1)为0


你想要那个 :

#include <stdio.h>
#include <limits.h>

unsigned rotright(unsigned x, int n)
{
   unsigned mask = (1u << (CHAR_BIT * sizeof(int) - 1));

  for (; n > 0; n--) {
    x = (x / 2) | ((x & 1) ? mask : 0);
  }
  return x;
}

int main()
{
    printf("%d\n", rotright(213, 2));
    return 0; 
}

在32位上,结果是1073741877是1000000000000000000000000110101,而不是117,假设你在8位工作

© www.soinside.com 2019 - 2024. All rights reserved.