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

nn=1Y2kn
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
原创粉丝点击