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\r\n", srl((unsigned)-1, w-1));
printf("sra(-1,1), expect:-1, result:%d\r\n", sra(-1, 1));
printf("((unsigned)-1) >> w-1, result:%d\r\n", ((unsigned)-1) >> (w-1));
printf("-1>>1 : result : %d\r\n", -1>>1);
return 1;
}
邮箱:quiet_learn@163.com
本文版权归作者和博客园共有,欢迎转载,转载请在文章明显位置注明作者及出处,谢谢!