CSAPP 第二章 homework
来源:互联网 发布:淘宝中老年夏季女装 编辑:程序博客网 时间:2024/04/28 14:17
2.57:
void show_short(short s);void show_long(long long l);void show_double(double d);void show_bytes(char *p, int size);void show_short(short s) { printf("the value of short %d is:", s); show_bytes((char *)&s, sizeof(short));}void show_long(long long l) { printf("the value of short %lld is:", l); show_bytes((char *)&l, sizeof(long long));}void show_double(double d) { printf("the value of short %lf is:", d); show_bytes((char *)&d, sizeof(double));}
2.58:
/** 1 in little_endian* *((char *)&i) means :* 01 00 00 00 ----> 01 */int is_little_endian() { int i = 1; return *((char *)&i);}
2.59:
int graft(int x, int y) { return (x & 0xff) | (y & ~0xff); //或也可以改成+}
2.60:
unsigned int graft2(unsigned int x,unsigned char y, int offset) { return (x & ~(0xff << (offset << 3))) | (((unsigned int)y) << (offset << 3));}
2.61:
//Areturn !~x; //Breturn !x;//Creturn !~((x >> ((sizeof(int) - 1) << 3)); //Dreturn !(x & 0xff);
2.62:
return ~((~0)>>1); //~0 = -1
2.63:
int sra(int x, int k) { //arithmetically int xsrl = (unsigned) x >> k; unsigned first_bit = x & (0x1 << (sizeof(int) * 8 - 1)); return xsrl + (((!first_bit) + ~0) << (sizeof(int) * 8 - k));}unsigned srl(unsigned x, int k) { //logically unsigned xsra = (int) x >> k; unsigned first_bit = x & (0x1 << (sizeof(int) * 8 - 1)); return xsra & ~(~0 << (sizeof(int) * 8 - k));}
2.64:
int any_even_one(unsigned x) { return !!(x & 0xaaaaaaaa);}
2.65:
int even_ones(unsigned x) { x ^= (x >> 16); x ^= (x >> 8); x ^= (x >> 4); x ^= (x >> 2); x ^= (x >> 1); return !(x & 0x1);}
2.66:
int leftmost_one(unsigned x) { x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; return (x>>1) + 1;}
2.67:
int int_size_is_32(){ int set_msb = 1 << 31; int beyond_msb = (1 << 16) << 16; return set_msb && !beyond_msb;}int better_int_size_is_32() { int seb_msb = ((1 << 8) << 8) << 15; int beyond_msb = (((1 << 8) << 8) << 8) << 8; return seb_msb && !beyond_msb;}
2.68:
//原题有点歧义,参数x没起到作用,于是把题目改成把x最低n位变成1int lower_byte(int x, int n) { return x | ((unsigned)(~0) >> (sizeof(int) * 8 - n));}
2.69:
unsigned rotate_right(unsigned x, int n) { return (x >> n) + ((x << (sizeof(int) * 8 - n - 1)) << 1);}
2.70:
int fits_bits(int x, int n) { x >>= (n - 1); return !x || !(x + 1);}
2.71:
return ((int)word << (3 - bytenum << 3)) >> (3 << 3);
2.72:
A:size_t是无符号类型,在和int类型计算的时候,int类型会被转换,得出的结果也是无符号的,所以始终都大于0B:maxbytes > 0 && maxbytes >= sizeof(val)
2.73:
int saturating_add(int x, int y) { int r = x + y; int tmp = r; int w = (sizeof(x) << 3) - 1; //x,y,r,取各自的符号位 x >>= w; y >>= w; r >>= w; //正溢出时x,y为0,算数位移计算出的r为0xffffffff => 计算出pos_of = 0xffffffff int pos_of = (~x)&(~y)&r; //负溢出时x,y为0xffffffff,r为0 int neg_of = x & y & (~r); //统统使用位运算 return (pos_of & TMAX) | (neg_of & TMIN) | tmp;}
2.74
int tsub_ovf(int x, int y) { int r = x - y; x >>= (sizeof(int) << 3) - 1; y >>= (sizeof(int) << 3) - 1; r >>= (sizeof(int) << 3) - 1; return (x != y)&&(r == y);}
2.75:
unsigned unsigned_high_prod(unsigned x, unsigned y) { //divide x(or y) into two parts the highest bit(xt or yt) and others(xr or yr) like this: //x => 0 000000000000000000000000000000 //unsigned x * y = (xt * 2^31 + xr) * (yt * 2^31 + yr) = xr * yr + xt * 2^31 * yr + yt * 2^31 * xr + xt * yt * 2^62 //and (unsigned) xr = (int)xr.So we can use the signed_high_prod() to calculate xr * yr unsigned xt = x >> sizeof(unsigned) - 1; unsigned yt = y >> sizeof(unsigned) - 1; unsigned xr = x & ~(1 << sizeof(unsigned) - 1); unsigned yr = y & ~(1 << sizeof(unsigned) - 1); return signed_high_prod(xr, yr) + (xt & yt) << 30 + (unsigned)(((int)xt << 31 >> 31) & yr) >> 1 + (unsigned)(((int)yt << 31 >> 31) & xr) >> 1 + add_of(xr * yr, (unsigned)(((int)xt << 31 >> 31) & yr) << 31,(unsigned)(((int)yt << 31 >> 31) & xr) << 31);}
2.76:
1. x << 2 + x2. x << 3 + x3. x << 5 - x << 14. x << 3 - x << 6
2.77:
//c语言除法规则是向零舍去int divide_power2(int i, int k) { return (i + ((1 << k) - 1) * (i < 0)) >> k;}
2.78:
//参考了网上思路//设x 为 b[w - 1], b[w - 2] ... b1, b0//x * 5 => (x << 2) + x//x * 5 / 8 = >//(b[w - 3] ... b1, b0, 0, 0 + b[w - 1] ... b1, b0) >> 3 等价于//b[w - 3] ... b1 + b[w - 1] ... b3 + (b1 & b2)//并且 当x < 0时 需要进行舍入 也就是 x<0 && (x&0x7)时 结果需要加1int mul5div8(int x) { int b0 = x & 1; int b2 = x & 0x4; int result = (x >> 1) + (x >> 3) + (b0 && b2); result += (x >> ((sizeof(int) << 3) - 1)) && (x&0x7); return result;}int main() { int i = 0x80000000; while(i < 0x7fffffff) { int ans_me = mul5div8(i); int ans_std = (long)5 * i / 8; if(ans_me != ans_std) printf("%d %d %d\n", i, ans_me, ans_std); i++; }}
2.80:
1. (~0) << n2. ((~0) << m) + (0x1 <<(m + n))
2.81:
1. false y = TMIN2. true3. false x = 0, y = 04. true5. true
2.82
2.83~2.90忘保存了..
2.91 ~ 2.96
工具函数
float u2f(unsigned u) { return *((float*)&u);}unsigned f2u(float f) { return *((unsigned*)&f);}int NaN(float_bits f) { int exp = (f>>23) & 0xff; int frac = f & 0x7fffff; return exp == 0xff && frac != 0;}int is_INF(float_bits f){ int exp = (f>>23) & 0xff; int frac = f & 0x7fffff; return exp == 0xff && frac == 0;}int float_equal(float_bits f1, float f2) { return f1 == f2u(f2);}//测试函数,对于不同的题目需要进行相应的修改int test(int (*fun1)(float_bits), int (*fun2)(float)) { unsigned u = 0; do{ int me = fun1(u); int std = fun2(u2f(u)); if(me != std) printf("error!!!\nu= %d, %x \nme is %x \nstd is %x \n", u, u, me, std); u++; }while(u!=0); printf("all finished"); return 0;}
2.91:
//isnan 和 fabs 都是math.h中的方法float_bits float_absval(float_bits f) { return NaN(f) ? f : f&~(1<<(sizeof(float_bits)<<3) - 1);}float myfabs(float f) { if(isnan(f)) return f; else return fabs(f);}
2.92:
float_bits float_negate(float_bits f) { if(NaN(f)) return f; else return f + (1 << (sizeof(float_bits)<<3) - 1);}float myfneg(float f) { if(isnan(f)) return f; return -f;}
2.93:
float_bits float_half(float_bits f) { if(NaN(f) || is_INF(f)) return f; unsigned sign = f & 0x80000000; unsigned exp = f & 0x7f800000; if(exp > 0x00800000) return f - 0x00800000; f &= ~(1<<31); //需要位移 先舍去符号位 //向偶数舍入 unsigned b1 = f & 0x2; unsigned b0 = f & 0x1; b1 >>= 1; f >>= 1; f += (b1 & b0); return sign + f;}float myhalf(float f) { if(isnan(f)) return f; return f / 2;}
2.94:
float_bits float_twice(float_bits f) { if(NaN(f) || is_INF(f)) return f; unsigned sign = f & 0x80000000; unsigned exp = f & 0x7f800000; if(exp == 0) return (f << 1) + sign; //非规格化时 else if(exp == 0x7f000000) return sign + 0x7f800000; //计算以后会产生溢出时 return f + 0x00800000;}float mytwice(float f) { if(isnan(f)) return f; else return f*2;}
2.95:
//乱的一比 等有时间再改改float_bits float_i2f(int i) { if(i == 0) return 0; //0 if(i == 0x80000000) return 0xcf000000; //TMin unsigned sign = i & 0x80000000; if(i < 0) i = -i; //统一正负数 unsigned x = i & 0x7fffffff; unsigned exp = 0x3f800000; //设置阶码为Bias(数值0) unsigned frac = 0; int pos = 0; while((x>>=1)!=0) //最高位所在的位置,0<=pos&&pos<=31 pos++; x = i & 0x7fffffff; if(pos <= 23) //pos <= 23不需要考虑舍入的情况 frac = (x<<23 - pos) & 0x007fffff; else{ //需要考虑舍入, unsigned b0 = x & ~((~0) << pos - 23); unsigned b1 = (x >> pos - 23) & 1; if(b0 > (1 << pos - 24) || (b0 == (1 << pos - 24) && b1 == 1)) x += (1 << pos - 23); frac = (x >> pos - 23) & 0x007fffff; //最容易被忽略的 在舍入中产生了进位 if((x >> pos + 1) == 1) pos++; } exp += pos << 23; return sign + exp + frac; }float myi2f(int i) { return (float)i;}
2.96:
//做完上一题以后这道题就清爽了好多#define BIAS 0x3f800000int main() { test(float_f2i, myf2i); return 0;}int float_f2i(float_bits f) { int ans = 0; unsigned sign = f & 0x80000000; unsigned exp = f & 0x7f800000; unsigned frac = f & 0x007fffff; frac += 0x00800000; if(exp < BIAS) return 0; //f < 1 if(exp > BIAS + (30 << 23)) return 0x80000000; //f > TMax int pos = (exp - BIAS) >> 23; if(pos <= 23) ans = frac >> 23 - pos; else ans = frac << pos - 23; return sign == 0 ? ans : -ans;}int myf2i(float f) { return f;}
1 0
- CSAPP 第二章 homework
- CSAPP读书笔记第二章:
- CSAPP 第二章
- CSAPP3e-第二章Homework
- CSAPP chapter3 homework
- csapp第二章学习笔记
- CSAPP 第二章 思维导图
- CSAPP 3rd 第二章家庭作业
- CSAPP深入理解计算机系统第二章学习笔记(1)
- [CSAPP笔记][第二章信息的表示和处理]
- CSAPP第二章-信息的表示和处理
- CSAPP 第二章 信息的表示和处理
- CSAPP(深入理解计算机系统)第二版家庭作业答案-第二章
- CSAPP阅读笔记——第二章:信息的表示和处理
- 《CSAPP》第一章,第二章总结——来记一篇流水账吧
- CSAPP(深入理解计算机系统)第二版家庭作业答案-第三章
- csapp第三章读书笔记
- CSAPP第四章读书笔记
- 朋友说这些都是干货,快收藏起来吧,嘿嘿!
- Swift学习笔记(Page.1)
- typedef和#define的用法与区别
- 写给开发者
- angularjs 解决之前的遗留的一个问题
- CSAPP 第二章 homework
- Nginx 限制连接数与请求数
- IDA工具的使用(持续更新)
- ubuntu 中vim的安装
- 数据库设计常见错误
- 判断网络图片是否存在
- linux初接触
- Swift设计模式之保护代理模式
- 正则表达式 捕获组,向前引用,零宽度断言,贪婪量词,惰性量词以及支配量词