答案参考了过去几版的答案
2.58##
编写过程is_little_endian在小端法的机器上返回1,大端法机器上返回0
int is_little_endian(){
int i = 1;
int j = (int)(*(char *)(&i));
return j;
}
2.59##
编写一个表达式,生成一个字,由x的最低有效字节和y中剩下的字节组成
(x&0xff)|(y&~0xff)
这里的取反比较精髓
2.60#
编写replace_byte(unsigned x,int i , unsigned char b) 将x的第i位置换成b
unsigned replace_byte(unsigned x,int i ,unsigned char b){
unsigned mask=b<<(i)*8;
unsigned mask2=0xff<<(i)*8;
return (x&~mask2)|(mask);
}
2.61##
编写一个表达式,在下列情况下等于一否则等于零
1 x的任何位都是1 !!~x
2 x的任何位都是0 !!x
3 最低有效位的数字都等于一
4 最低有效位的数字都等于零
34类似添加掩码操作就可以了
2.62##
编写一个程序在算术右移的机子上返回1 否则返回0
int i=-1;
这里使用 ~0更好 -1也许不具有普遍性但是~0总是具有普遍性的
(i>>1)==x
2.63##
补全下列C语言代码
用逻辑右移实现算术右移、用算数右移实现逻辑右移 (禁用右移和除法)
unsigned srl(int x,int k){
//用算术扩展实现逻辑扩展
int xsrl=x>>k;
就是将补位置0 要获得
形如 00011111的掩码 ,我一直想着~0右移得到。十分的不靠谱
最好的获得方法是0010000的形式减一 而且只使用了左移操作
还有一个问题是确定int数据类型的位数
使用8*sizeof(int)
}
int srl ()
//使用逻辑扩展实现算数扩展
//就是将w-k-1位的值扩展上去
根据w-k-1位的值获得相应的掩码
如果是1 掩码就是 11111110000000
是0掩码就是 0000000000000
对左侧取反加一如果是零那么结果就是全零,如果是1结果就是全一
再利用一个掩码分割处理字节序列的左和右##
2.64##
写程序 如果给定序列的任意奇数位位1 就返回1 否则就返回0
(可以假设int 长32位)
手写常量
!!(x&0xAAAA)
2.65##
如果是奇数的1就返回1 否则返回0
int odd_ones(unsigned x){
x^=(x>>16);
x^=(x>>8);
x^=(x>>4);
x^=(x>>2);
x^=(x>>1);
return(x&1);
}
6.26##
找出最左侧的bits 1(可以假设int的位宽是32位的)
不超过15次的运算
int left_mostone(unsigned x){
x|= x>>16;
x|= x>>8;
x|= x>>4;
x|= x>>2;
x|= x>>1;
x>>=1;
x+=1;
//或者 x^(x>>1) ;//更为优雅
return x;
}
修改代码使得可以判断int类型的位数
1在那个方面没有遵守c语言的标准
不可以移位超过32位
+
+3
.