在很多语言(如:C和Java)中都提供了移位运算,它包括:左移运算和右移运算两种。
其中,左移运算(<<)比较简单和固定,X向左移k位,即是丢弃最左端的k位,并在右端补k个0。
而右移运算有两种类型,一种是叫逻辑右移,另一种是算术右移。X右移k位这个操作,在逻辑右移中,为舍弃最右端的k位,并在左端补k个0,而在算术右移中,它表示为在左端补k个最高有效位的值(可能是0也可能是1)。
在C语言中,右移运算统一表示为 X>>k,C语言标准没有明确定义应该使用哪种类型的右移。对于无符号数据,右移必须是逻辑右移。而对于有符号数据,算术右移和逻辑右移都可以。实际上,在多数的编译器和及处理器架构的组合中,对有符号数据使用算术右移。
在Java语言中,对两种右移类型有不同的表示,表达式X>>k表示将X算术右移k位,而X>>>k表示将X逻辑右移k位。
注:在IA架构下,左端表示高位,而右端表示低位。
分别写了下面两个C和Java的小程序来看右移运算。
C语言代码如下:
#include
/*
* To test shifting for unsigned int and signed int.
*/
int main(int argc, char *argv[])
{
unsigned int a = 0x80000000;
int b = 0x80000000;
unsigned int c = 0x00000008;
int d = 0x00000008;
printf("a=%u, hexadecimal format:%x\n", a, a);
printf("b=%d, hexadecimal format:%x\n", b, b);
printf("a>>2 is %u, hexadecimal format:%x\n", a>>2, a>>2);
printf("b>>2 is %d, hexadecimal format:%x\n", b>>2, b>>2);
printf("(a>>2) ^ (b>>2) is 0x%x\n", (a>>2)^(b>>2));
printf("c=%u, hexadecimal format:%x\n", c, c);
printf("d=%d, hexadecimal format:%x\n", d, d);
printf("c>>2 is %u, hexadecimal format:%x\n", c>>2, c>>2);
printf("c>>2 is %d, hexadecimal format:%x\n", d>>2, d>>2);
printf("(c>>2) ^ (d>>2) is 0x%x\n", (c>>2)^(d>>2));
printf("sizeof(int) = %lu\n", sizeof(int));
}
运行结果为:
master@jay-intel:~/workspace/c-study$ ./shift-test
a=2147483648, hexadecimal format:80000000
b=-2147483648, hexadecimal format:80000000
a>>2 is 536870912, hexadecimal format:20000000
b>>2 is -536870912, hexadecimal format:e0000000
(a>>2) ^ (b>>2) is 0xc0000000
c=8, hexadecimal format:8
d=8, hexadecimal format:8
c>>2 is 2, hexadecimal format:2
c>>2 is 2, hexadecimal format:2
(c>>2) ^ (d>>2) is 0x0
sizeof(int) = 4
Java程序:
/**
* @className: ShiftTest.java
* @author: 笑遍世界
* @description: Java中的算术移位与逻辑移位
* @date 2012-04-19
*/
public class ShiftTest {
public static void main(String[] args) {
int a = 0x80000000;
int a1 = a>>2; //算术移位
int a2 = a>>>2; //逻辑移位
System.out.println("a is " + a + "; "+Integer.toBinaryString(a));
System.out.println("a>>2 is " + a1 + "; "+Integer.toBinaryString(a1));
System.out.println("a>>>2 is " + a2 + "; "+Integer.toBinaryString(a2));
System.out.println("integer size is " +Integer.SIZE);
}
}
运算结果为:
master@jay-intel:~/workspace/java-study/bin$ java ShiftTest
a is -2147483648; 10000000000000000000000000000000
a>>2 is -536870912; 11100000000000000000000000000000
a>>>2 is 536870912; 100000000000000000000000000000
integer size is 32
以上代码在Intel平台的Linux环境上运行的。