c - 16 位非负数的右旋?

标签 c rotation bitwise-operators unsigned

我正在研究一种需要执行正确旋转的方法。比如我有一个二进制数0101110111000111,执行该方法后结果应该是1010111011100011。传入一个16位非负数作为参数,这个参数值会将所有位右移移动 1 位,并将低位移动到高位(如上例)。

这是我写的代码。我将 0101110111000111 转换为十进制值 24007。

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

unsigned int rotateRight(unsigned int x);

int main(int argc, char **argv) {
  unsigned int n = 24007; 
  printf("%d\n", rotateRight(n, d)); 
  return 0; 
} 

/*Function to right rotate n by d bits*/
unsigned int rotateRight(unsigned int x) {
  return (x >> 1) | (x << (16-1));
}

我的预期结果应该是 44771 的值,因为它的十进制等于 1010111011100011。但是,当我运行这个程序时,我得到 786673379。有人可以解释为什么会这样,以及我如何改进我的旋转功能这样我就能得到正确答案?

最佳答案

(x << (16-1)将整个 16 位数量向左移动 15 位并将其添加到 x >> 1 之前.自 int可以保存 32 位值,因此不会截断您的计算,结果您会得到一个 31 位值。

x = 0101 1101 1100 0111
x >> 1 = 0010 1110 1110 0011
x << (16 -1) = 0010 1110 1110 0011 1000 0000 0000 0000

=> (x >> 1) | (x << (16-1))
    = 0101110111000111010111011100011 (binary)
    = 786673379 (decimal)

一个解决方案是:

unsigned int rotateRight(unsigned int x) {
  return ((x >> 1) | (x << (16-1))) & 0xffff;
}

即执行您已经在执行的计算,但只保留最低的 16 位。

或者,您可以使用类似 uint16_t 的类型以确保自动截断较大的数字,具体取决于您对隐式类型转换和显式类型转换语法的感受。

关于c - 16 位非负数的右旋?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57246445/

相关文章:

c - 如何将8位int8变量放入char变量中?

c - Android 中的套接字问题

SVG以%为单位旋转文本

javascript - 计算 32 次方的对数最快的方法是什么?

c - 打印每个单词的第一个字母 C

c - 将 freeRTOS 集成到现有项目

java - LibGDX 旋转 Sprite 时出现问题

r - 计算尺寸 >3 的欧拉角/Tait-Bryan 角的模拟

javascript - 如何强制按位运算符产生无符号结果?

python-3.x - 是否有用于标志/位掩码操作的 Python 类/枚举?