1. C语言的移位

在C语言中,左移为逻辑移位,即左移右侧补0;右移为算术移位,即右移左侧补符号位。

  1. 上述程序对 -2 进行左移一位和右移一位的操作,可见-2在内存中存储为ffffffffe即11111111 11111111 11111111 1111 1110;
  2. -2经过左移一位后变为:11111111 11111111 11111111 1111 1100为-4,可见左移操作时为逻辑左移,在右侧补0;
  3. -2经过右移一位后变为: 11111111 11111111 11111111 11111111;可见右移操作时将最左侧补为1,即符号位1,所以右移操作为算术右移。

2. 利用算术右移实现逻辑右移

本质上就是先把(int)x右移k位,然后将0xffffffff左移sizeof(int)*8-k位后取反,得到的就是串 00000…1111111111,其中有k个0,然后做与运算。即将高位符号位1变为0,低位保持不变。

//算术右移完成逻辑右移
unsigned srl(unsigned x,int k){
    /*Perform shift arithmetically*/
    unsigned xsra = (int)x >> k;
    unsigned wei = 8*sizeof(int);
    unsigned left = -1 << (wei-k);
    //0xffffffff左移wei-k位,取反得到000...1111与xsra相与
    return xsra&(~left);
}

3. 利用逻辑右移实现算术右移

//逻辑右移完成算术右移
int sra(int x,int k){
    /*Perform shift logically*/
    int xsrl = (unsigned) x>>k;
    int wei = 8*sizeof(int);
    //0x00000001左移wei-k-1位,和原数符号位对齐,做与运算
    int left = 1 << (wei-k-1);
    if(left&xsrl){//为真,说明符号位为1
        return (-1<<(wei-k))|xsrl; //补上符号位的1
    }
    //符号位为0,直接返回
    return xsrl;
}

更多推荐

C语言的移位操作