我正在查看一些将无符号整数移位32次的代码,但发现很难理解移位运算符与OR运算符的结合使用。
执行时究竟是做了什么?
作为一个例子,如果将变量设置为:
,结果会是什么_arg1 = 1
_arg2 = 20
((_arg1 << _arg2) | (_arg1 >> (32 - _arg2)))
如果变量有更容易的值来解释,可以随意更改它们以更好地满足您的需求。
非常感谢提前。
答案 0 :(得分:4)
&LT;&LT;和&gt;&gt;是移位运算符,它通过arg2位置移动变量的位......
所以如果你有:
11001010 << 2
你会将整个位串向左移动两个。这实际上将前两个(从左侧)位推出变量,并从右侧推入一些0。所以:
11001010&lt;&lt; 2 = 00101000
在你的问题中,你正在进行轮换。
所以我们假设arg1 = 11001010(二进制)和arg2 = 2,当我们使用8位整数时,我们将32替换为8。
((11001010 << 2) | (11001010 >> (8 - 2)))
= (00101000 | 00000011)
现在是|将两个位串连接到一个,所以如果在一个字符串中设置了一个位,它现在也将在结果中设置:
(00101000 | 00000011) == 00101011
那么你的代码实际上在做什么?它被称为圆形或旋转移位...它在一侧推出的位,它实际上从另一侧推入。因此,您可以旋转位图,而不是仅将一侧移到任何一侧,并在另一侧添加零。
答案 1 :(得分:1)
这将适用circular shift。
让我们举个例子:
uint32_t _arg1 = 0xc2034000;
uint32_t _arg2 = 2;
二进制
_arg1 = 11000010000000110100000000000000
_arg2 = 00000000000000000000000000000010
通过_arg2位将_arg1向左移位,实际上这意味着从_arg1中删除_arg2位数创建一个数字(从左边开始并添加0作为附加值)
_arg1 = 11000010000000110100000000000000
^^
result is 00001000000011010000000000000000
将_arg1向右移动(32 - _arg2)位,实际上这意味着通过从_arg1中删除(32 - _arg2)位数来创建一个数字(从右边开始并添加0作为附加值),所以获取之前删除的_arg2位
_arg1 = 11000010000000110100000000000000
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
result is 00000000000000000000000000000011
这将连接对左侧和右侧参数中的每两个相应位应用逻辑OR运算。
((_arg1 << _arg2) | (_arg1 >> (32 - _arg2)))
result is 00001000000011010000000000000011
std :: bitset对于使用位集非常有用,因为您可以轻松地查看代码中的内容。
答案 2 :(得分:0)
将语句分成小部分,首先取(_arg1&lt;&lt; _arg2)这意味着 1&lt;&lt; 20,现在计算值,如果1向左移动20个位置,那么二进制值看起来像100000000000000000000(每次1向左移0将填充在1的位置),结果为1048576。
现在取另一部分,(_ arg1&gt;&gt;(32 - _arg2)))这意味着 1&gt;&gt; 12.因为1是最小的正值,所以如果我们将1向右移动一个位置,它将变为0.
我们现在完成了两个部分,我们将对我们得到的两个结果进行按位OR运算,即 100000000000000000000 | 0
我们会像
一样100000000000000000000
0
现在我们将按位(垂直)对两个值进行OR运算,这将给出100000000000000000000,其十进制值为1048576。 您可以参考下表进行按位OR运算。
0 0 = 0
0 1 = 1
1 0 = 1
1 1 = 1