循环移位c

use*_*300 26 c

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

y = (x << shift) | (x >> (sizeof(x)*CHAR_BIT - shift));
Run Code Online (Sandbox Code Playgroud)

我在循环转换文章中找到了但没有解释它是如何工作的.

Die*_*Epp 26

这是一种循环移位的方法.假设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,那么右移是错的.但是,当按类型宽度移动时,这适用于所有三种常见行为.(实际上,移位量减少了一些模数 - 要么是类型的位宽,要么是更大的数字.)

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

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

  • +1,但是8并不是未定义移位量的一个很好的例子,因为按照通常的算术转换,移位类型至少是(有符号或无符号)`int`,而`int`至少是16位. (3认同)

thu*_*eys 18

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

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

     1110 0000 << 2 results in:
     1000 0011
Run Code Online (Sandbox Code Playgroud)

该示例的代码:

   y = (x << 2) | (x >> (8 - 2));
Run Code Online (Sandbox Code Playgroud)

  • 对于你将在21世纪使用的任何理智的建筑,CHAR_BIT总是8 :-) (5认同)
  • @PascalCuoq`x >> 8 - 2`被解析为`x >>(8 - 2)`并带有警告:**运算符'>>'的优先级低于' - '; ' - '将首先评估[-Wshift-op-parentheses]** (2认同)

Ani*_*han 5

(x << shift) 
Run Code Online (Sandbox Code Playgroud)

向左移动“位数”位数,返回移出的位数

(x >> (sizeof(x)*CHAR_BIT - shift));
Run Code Online (Sandbox Code Playgroud)

留出空间容纳这些位

CHAR_BIT是char中的位数,所以大多数是8。在C语言中,您一次不会处理一位,但至少要处理char个位数。这就是您获得的粒度。

一般来说,

对于char,当您进行位旋转时,将在8位字段(1个字节)上进行

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


8位示例:

x = 11010101
shift = 2

x << (shift) = 01010100 //shifted right by 2 bits

= x >> ((1 * CHAR_BIT) - shift)
= x >> (6) 
= 00000011 //shifted left by 6bits
Run Code Online (Sandbox Code Playgroud)

OR 这些都给

01010100 //x << 2
00000011 //x >> 6
________
01010111
Run Code Online (Sandbox Code Playgroud)

那是循环移位值2位