循环移位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个字节长)。 所以,它也依赖于类型。