题目:将下面的C函数代码补充完整。函数srl用算数右移(由值xsra给出)来完成逻辑右移,后面的其他操作不包括右移或者除法。函数sra用逻辑右移(由值xsrl给出)来完成算数右移,后面的其他操作不包括右移或者除法。函数sra用逻辑右移(由值xsrl给出)来完成算数右移,后面的其他操作不包括右移或者除法。可以通过计算8*sizeof(int)来确定数据类型int中的位数w。位移量k的取值范围为0~w-1。
代码如下:
#include<stdio.h>
unsigned srl(unsigned x,int k){
unsigned xsra=(int)x>>k;
int w=sizeof(int)*8;
// int a=~(-1<<(w-k)); ///如果k=0怎么办,需要用其他逻辑替换
int a=~ (((-1 << (w-k-1)) & xsra) << 1);//(-1 << (w-k-1)) & xsra保留xsra最高位不变,然后左移一位对齐
return a&xsra;
}
int sra(int x,int k){
int xsrl=(unsigned)x>>k;
int m=-1<<(sizeof(int)*8-k-1); //无符号逻辑位移,位移补0,关键在于判断sizeof(int)*8-k-1高位值是否为1,如果为1就取反,为0就不变
printf("m %.2x",m);
printf("\n");
int n =(~((xsrl & m) + m) & m) << 1 ; // xsrl&m,保持第w-k-1为原符号位,其他位归0,然后+m,保持第w-1位是原符号位的反,w-1后的位为0,,然后取反,回归符号位,然后左移1位,对齐原符号位。
printf("xsrl %.2x",xsrl);
printf("\n");
printf("xsrl & m %.2x",xsrl & m);
printf("\n");
printf("(xsrl & m)+m %d",(~((xsrl & m) + m) & m) << 1);
printf("\n");
printf("n %.2x",n);
printf("\n");
return xsrl|=n;
}
int main()
{
unsigned test_unsigned=0x1F;
int test=-1;
printf("test srl %d",srl(test_unsigned,3) == test_unsigned >> 3);
printf("\n");
printf("test sra %d",sra(test,2) == test >>2);
return 0 ;
}