个人答案第二章

答案参考了过去几版的答案

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
.

原文地址:https://www.cnblogs.com/sfzyk/p/7613266.html