2.63 还原算数右移,逻辑右移

Posted lonelytraveler

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2.63 还原算数右移,逻辑右移相关的知识,希望对你有一定的参考价值。

//csapp 2.63, 还原算数右移,逻辑右移

#include <stdio.h>

unsigned srl(unsigned x, int k)
{   
    /* Perform shift arithmetically */
    unsigned xsra = (int) x >> k;
    //begin this
    //此处由于转换成int,原来的逻辑右移变成了算数右移,通过以下代码还原为逻辑右移
    //逻辑右移,高位补0,产生w-k 位之前的数据位为0,之后的位为1
    unsigned w = sizeof(unsigned)<<3;
    int mask = (1 << (w-k)) -1; 
    return xsra & mask;
}   

int sra(int x, int k)
{   
    /* Perform shift logically */
    int xsrl = (unsigned) x >> k;
    //begin this
    //此处由于转换为无符号数,右移变为逻辑右移,通过以下代码还原为算数右移
    unsigned w = sizeof(unsigned)<<3;
    //最高有效位数据位,如果数据不为0,则代表应该进行算数右移,
    //w-k-1, w-k会比原来数据高出一位
    int bit_data = (1 << (w-k-1)) & xsrl;
    //1. bit_date==0,次数为正数,不需要处理, 此时-1取反的数据还是0,
    //2. bit_date不为0,次数为负数,高位填充1,此时-1使高位还为0,低位全为1,取反后高位全为1
    int mask = ~(bit_data-1);

    return xsrl | mask;
}   

int main(void)
{   
    unsigned w = sizeof(unsigned)<<3;
    printf("srl((signed)-1,w-1), expect:1, result:%d
", srl((unsigned)-1, w-1));
    printf("sra(-1,1), expect:-1, result:%d
", sra(-1, 1));
    printf("((unsigned)-1) >> w-1, result:%d
", ((unsigned)-1) >> (w-1));                                                                                                       
    printf("-1>>1 : result : %d
", -1>>1);
    return 1;
}

以上是关于2.63 还原算数右移,逻辑右移的主要内容,如果未能解决你的问题,请参考以下文章

GNU汇编逻辑或算数左移右移

算法——位运算

2.62 判断机器是否进行算数右移

2.62 判断机器是否进行算数右移

C语言位操作

C语言位操作