>>
和<<
,但我并不理解它们的实际作用和实际用途。如果这些移位操作与x * 2
和x / 2
类似,那么使用*
和/
运算符会有什么区别呢?它们的性能有差异吗?>>
和<<
,但我并不理解它们的实际作用和实际用途。如果这些移位操作与x * 2
和x / 2
类似,那么使用*
和/
运算符会有什么区别呢?它们的性能有差异吗?这里有一个小程序,你可以在其中进行一些位运算,包括位移。
你有一组比特,并且你移动其中的一些比特超出了它们的边界:
1111 1110 << 2
1111 1000
它从右边用新的零填充。 :)
0001 1111 >> 3
0000 0011
从左侧填充。一个特殊情况是前导1。它通常表示负值-具体取决于语言和数据类型。因此,如果要向右移位,则通常希望第一位保持不变。
1100 1100 >> 1
1110 0110
并且这种方法在多次转换中是不变的:
1100 1100 >> 2
1111 0011
如果您不想保留第一位,您可以使用三个相同符号的运算符(在我所知道的Java、Scala、C++、C中,可能还有其它语言也支持):
1100 1100 >>> 1
0110 0110
在其他方向上没有相应的等价物,因为这没有任何意义——也许在你非常特殊的情况下可以,但不是普遍的。
数学上,左移一位是*=2,两次左移是*=4等等。右移一位是/= 2等等。
2
4
6
8
还是 2
4
8
16
? - S.S. Anne左移位操作可以用来将一个数乘以 2 的任意次方,而 右移 操作可以用来将一个数除以 2 的任意次方。
例如,x = x * 2;
可以写成 x<<1
,而 x = x*8
可以写成 x<<3
(因为 2 的 3 次方是 8)。同样地,x = x / 2;
可以写成 x>>1
等等。
x = x * 2^value
(正常运算)
x << value
(位运算)
x = x * 16
(相当于2^4
)
左移的等价操作为 x = x << 4
x = x / 2^value
(正常算术操作)
x >> value
(位运算)
x = x / 8
(相当于2^3
)
右移的等价操作为 x = x >> 3
左移:它等于要进行移位的值乘以2的移位的位数次方。
例如:
1 << 3
0000 0001 ---> 1
Shift by 1 bit
0000 0010 ----> 2 which is equal to 1*2^1
Shift By 2 bits
0000 0100 ----> 4 which is equal to 1*2^2
Shift by 3 bits
0000 1000 ----> 8 which is equal to 1*2^3
右移:它等于要进行位移的值除以2的位数次方所得的商。
例如:
8 >> 3
0000 1000 ---> 8 which is equal to 8/2^0
Shift by 1 bit
0000 0100 ----> 4 which is equal to 8/2^1
Shift By 2 bits
0000 0010 ----> 2 which is equal to 8/2^2
Shift by 3 bits
0000 0001 ----> 1 which is equal to 8/2^3
比较起除(/
)或乘(*
)运算符,位移运算符更加高效。
在计算机架构中,除法(/)或乘法(*)需要多个时间单位和寄存器来计算结果。而位移运算符只需要一个寄存器和一个时间单位进行计算。
左移位运算可用于乘以2的任意次幂。 右移位运算可用于除以2的任意次幂。
x = x << 5; // Left shift
y = y >> 5; // Right shift
#include <math.h>
x = x * pow(2, 5);
y = y / pow(2, 5);
一些例子:
1 << 4
等于2^4
即16)1 << 4
或1 << 5
定义常量更易读。我认为在性能方面,您可能会发现按位左移和右移操作可以在大数据集的情况下以o(1)的复杂度执行,从而提高效率。
例如,计算2 ^ n的幂:
int value = 1;
while (exponent<n)
{
// Print out current power of 2
value = value *2; // Equivalent machine level left shift bit wise operation
exponent++;
}
}
使用按位左移操作的类似代码如下:
value = 1 << n;
这里是一个例子:
#include"stdio.h"
#include"conio.h"
void main()
{
int rm, vivek;
clrscr();
printf("Enter any numbers\t(E.g., 1, 2, 5");
scanf("%d", &rm); // rm = 5(0101) << 2 (two step add zero's), so the value is 10100
printf("This left shift value%d=%d", rm, rm<<4);
printf("This right shift value%d=%d", rm, rm>>2);
getch();
}