循环移位c

以下代码如何工作以及变量的含义:

y = (x <> (sizeof(x)*CHAR_BIT - shift)); 

我在一篇循环移位文章中找到了但没有解释它是如何工作的。

CHAR_BIT是每字节的位数,应始终为8。

shift是您想要以循环方式向左移位的位数,因此向左移出的位返回右侧。

  1110 0000 << 2 results in: 1000 0011 

该示例的代码:

  y = (x << 2) | (x >> (8 - 2)); 

这是一种循环移位的方法。 假设x是8位。

 + ---- ---- + ---- + ---- + ---- + ---- + ---- + ---- + +
 |  x1 x2 x3 x4 x5 x6 x7 x8 |
 + ---- ---- + ---- + ---- + ---- + ---- + ---- + ---- + +

然后,将它向左移3给我们:

 + ---- ---- + ---- + ---- + ---- + ---- + ---- + ---- + +
 |  x4 x5 x6 x7 x8 0 0 0 |
 + ---- ---- + ---- + ---- + ---- + ---- + ---- + ---- + +

现在, CHAR_BIT*sizeof(x)x的宽度相同,为8位。因此将x向右移动8 - 3给出了:

 + ---- ---- + ---- + ---- + ---- + ---- + ---- + ---- + +
 |  0 0 0 0 0 x1 x2 x3 |
 + ---- ---- + ---- + ---- + ---- + ---- + ---- + ---- + +

你拿到了OR:

 + ---- ---- + ---- + ---- + ---- + ---- + ---- + ---- + +
 |  x4 x5 x6 x7 x8 x1 x2 x3 |
 + ---- ---- + ---- + ---- + ---- + ---- + ---- + ---- + +

这在技术上是不便携的,因为它不能移动一个等于类型宽度的数量 – 所以如果shift是8,那么左移是错误的,如果移位是0,那么右移是错的。 但是,当按类型宽度移动时,这在所有三种常见行为中都有效。 (实际上,移位量减少了一些模数 – 要么是类型的位宽,要么是更大的数字。)

它被称为循环移位或“旋转”,因为在左侧移出的位在右侧向后移位。

复杂的编译器实际上会将代码编译为硬件循环指令。

 (x << shift) 

将它向左移位'位',返回移出的位

 (x >> (sizeof(x)*CHAR_BIT - shift)); 

为容纳这些位提供空间

CHAR_BIT是char中的位数,因此大部分是8。 在C中,您不能一次处理一个位,但至少是char位数。 这就是你得到的粒度。

一般来说,

对于char,当你进行位旋转时,你可以在8位字段(1字节)上进行

对于int,当你进行旋转时,你可以在32位字段上进行(4个字节)


8位示例:

 x = 11010101 shift = 2 x << (2) = 01010100 //shifted right by 2 bits = x >> ((1 * CHAR_BIT) - 2) = x >> (6) = 00000011 //shifted left by 6bits 

OR这些按位给予

 01010101 00000011 ________ 01010111 

这是循环移位值2位

这仅适用于无符号类型。 在带有有符号的负数的情况下,大多数左位将由右移运算符(“>>”)替换为最高有效位(1-s)的值

我这样写的:

 y = (x << shift) | ( (x >> (sizeof(x)*CHAR_BIT - shift)) & (0x7F >> (sizeof(x)*CHAR_BIT - shift) ); 

在这里之前“|” 运算符我们确认前n位(n = sizeof(x)* CHAR_BIT – 移位)归零。 我们还假设x很短(2个字节长)。 所以,它也依赖于类型。