码迷,mamicode.com
首页 > 移动开发 > 详细

CSAPP 3e : Data lab

时间:2017-09-14 18:42:05      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:ted   ice   tle   evel   float   否则   using   lease   oid   

/* 
 * CS:APP Data Lab 
 * 
 * <Please put your name and userid here>
 * 
 * bits.c - Source file with your solutions to the Lab.
 *          This is the file you will hand in to your instructor.
 *
 * WARNING: Do not include the <stdio.h> header; it confuses the dlc
 * compiler. You can still use printf for debugging without including
 * <stdio.h>, although you might get a compiler warning. In general,
 * it‘s not good practice to ignore compiler warnings, but in this
 * case it‘s OK.  
 */

/* 
 * bitAnd - x&y using only ~ and | 
 *   Example: bitAnd(6, 5) = 4
 *   Legal ops: ~ |
 *   Max ops: 8
 *   Rating: 1
 */
int bitAnd(int x, int y) {
  return ~(~x|~y);            //简单,不解释。
}
/* 
 * getByte - Extract byte n from word x
 *   Bytes numbered from 0 (LSB) to 3 (MSB)
 *   Examples: getByte(0x12345678,1) = 0x56     //指定n,获取第n个字节上的数字。0<=n<=3。
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 6
 *   Rating: 2
 */
int getByte(int x, int n) {
    n=n<<3;                    //n*=8,因为每个字节占8个二进制位。
    x=x>>n&0xff;            //x右移n位,即把需要获取的字节移到了最低号位,再用&操作取得目标字节(其余位置0)。
    return x;
}
/* 
 * logicalShift - shift x to the right by n, using a logical shift    //用算数移位实现逻辑移位(右)。
 *   Can assume that 0 <= n <= 31
 *   Examples: logicalShift(0x87654321,4) = 0x08765432
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 20
 *   Rating: 3 
 */
int logicalShift(int x, int n) {
    x=x>>n;                //算数右移。
    x=~((~0)<<(~n+32+1))&x;        //将因算数右移可能补1的n个位置0。(~n+32+1)实现(32-n),~n等于(-n-1)。
  return x;
}
/*
 * bitCount - returns count of number of 1‘s in word    //要求计算参数值得二进制位中1的个数。
 *   Examples: bitCount(5) = 2, bitCount(7) = 3    //用二分法。每次相加二分移位前后的值,则在相应的n个位上存储了该次
 *   Legal ops: ! ~ & ^ | + << >>                //二分中1的个数。eg:第一次移位操作移了移位,相加得的是相邻两个位中
 *   Max ops: 40                                //1的个数,最高值位2(b 10),需要两个位进行存储相加值。所以x&5,
 *   Rating: 4        //因为5二进制为 b 0101。第二次操作移2位,每一个计算单元(2+2=4个位上1的个数)最大值为4(b 100)
 */                //所以有x&3,3=(b 0011);  !重点应该发现x&(01)到(0011),再到(00001111)的变化,分别对应于二分移n位
int bitCount(int x) {    //的操作。
    x=(x&0x55555555)+(x>>1&0x55555555);        
    x=(x&0x33333333)+(x>>2&0x33333333);    
    x=(x&0x0f0f0f0f)+(x>>4&0x0f0f0f0f);
    x=(x&0x00ff00ff)+(x>>8&0x00ff00ff);
    x=(x&0x0000ffff)+(x>>16&0x0000ffff);
    /*x=(x+(x>>4))&0x0f0f0f0f;
    x = x + (x >> 8);              //此处是网上找到的方法,其实是一样的。这里后边没有0x00ff00ff是因为可以省略了。
    x = x + (x >> 16);            //不过需要最后x&0x3f的操作消去从第8位开始可能存在的1(二进制中)。
    x=x&0x3f;*/
  return x;
}
/* 
 * bang - Compute !x without using !
 *   Examples: bang(3) = 0, bang(0) = 1        //如果x!=0,x=(x|(~x+1))符号位为1,只有x==0时才为0;(注意这里说的是
 *   Legal ops: ~ & ^ | + << >>                //符号位)。
 *   Max ops: 12
 *   Rating: 4 
 */
int bang(int x) {
    x=(~((x|(~x+1))>>31))&1;    
  return x;
}
/* 
 * tmin - return minimum two‘s complement integer //返回int的最小值。即0x80000000;
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 4
 *   Rating: 1
 */
int tmin(void) {
  return (1<<31);
}
/* 
 * fitsBits - return 1 if x can be represented as an 
 *  n-bit, two‘s complement integer.
 *   1 <= n <= 32
 *   Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 15
 *   Rating: 2
 */
int fitsBits(int x, int n) {
    int shif=(~n+1+32);        //shif=(32-n);
    int def=~(~0<<n);        //def=1左移n位,但是不补0而是补1,比如得def=0x0000ffff;
    x=!!(x^((x<<shif)>>shif&def));        
  return x;
}
/* 
 * divpwr2 - Compute x/(2^n), for 0 <= n <= 30
 *  Round toward zero
 *   Examples: divpwr2(15,1) = 7, divpwr2(-33,4) = -2
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 15
 *   Rating: 2
 */
int divpwr2(int x, int n) {        //做这题的时候没有想到偏置量这个东西,后来在网上查了才知道的。
    //全0或者全1
    int signx = x >> 31;
    int mask = (1 << n)-1 ;//+ (~0);//得到2^n - 1
    int bias = signx & mask;//如果x是正数,则bias为0,即不用加,直接移位
    //如果x为负数,加上偏置量之后再移位
    return (x + bias) >> n;
}
/* 
 * negate - return -x 
 *   Example: negate(1) = -1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 5
 *   Rating: 2
 */
int negate(int x) {
  return ~x+1;
}
/* 
 * isPositive - return 1 if x > 0, return 0 otherwise 
 *   Example: isPositive(-1) = 0.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 8
 *   Rating: 3
 */
int isPositive(int x) {
    x=!(x>>31&0x1|!x);
    return x;
}
/* 
 * isLessOrEqual - if x <= y  then return 1, else return 0 
 *   Example: isLessOrEqual(4,5) = 1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 24
 *   Rating: 3
 */
int isLessOrEqual(int x, int y) {        //~~之后的慢慢理解,看着头疼。半个月之后回过来看这个简直了。。。
    int signx=x>>31;//如果x(y)为正数,则signx(signy)等于0;否则等于-1,即0xffffffff;
    int signy=y>>31;
    int same=((x+(~y))>>31)&(!(signx^signy));    //当x,y同号,求if x<=y;
    int differ=(!(y>>31))&(signx^signy);        //当x,y异号,求if x<=y;异号的话其实y是正数则x<=y成立。
  return same|differ
}
/*
 * ilog2 - return floor(log base 2 of x), where x > 0
 *   Example: ilog2(16) = 4
 *   Legal ops: ! ~ & ^ | + << >>    //理解方法是,在参数x的二进制位中,最左边的1是在第n位,则log(x)=n-1;
 *   Max ops: 90        //如:16的二进制是10000,最左边1在第5位,所以log(16)=5-1=4;也可以看到1右边有4个0;
 *   Rating: 4    
 */
int ilog2(int x) {
    int bitsNumber=0;
    bitsNumber=(!!(x>>16))<<4;
    bitsNumber=bitsNumber+((!!(x>>(bitsNumber+8)))<<3);
    bitsNumber=bitsNumber+((!!(x>>(bitsNumber+4)))<<2);
    bitsNumber=bitsNumber+((!!(x>>(bitsNumber+2)))<<1);
    bitsNumber=bitsNumber+((!!(x>>(bitsNumber+1))));
    bitsNumber=bitsNumber+((!!bitsNumber)+(~0)+(!(1^x)));
  return bitsNumber;
}
/* 
 * float_neg - Return bit-level equivalent of expression -f for
 *   floating point argument f.
 *   Both the argument and result are passed as unsigned int‘s, but
 *   they are to be interpreted as the bit-level representations of
 *   single-precision floating point values.
 *   When argument is NaN, return argument.
 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
 *   Max ops: 10
 *   Rating: 2
 */
unsigned float_neg(unsigned uf) {
    unsigned result;
    unsigned tmp;
    result=uf ^ 0x80000000; //将符号位改反
    tmp=uf & (0x7fffffff);
    if(tmp > 0x7f800000)//此时是NaN
        result = uf;
    return result;
}
/* 
 * float_i2f - Return bit-level equivalent of expression (float) x
 返回int x的浮点数的二进制形式。
 *   Result is returned as unsigned int, but
 返回的是unsigned型但是表示的时二进制单精度形式
 *   it is to be interpreted as the bit-level representation of a
 *   single-precision floating point values.
 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
 *   Max ops: 30
 *   Rating: 4
 */
unsigned float_i2f(int x) {            //浮点这里是直接“借鉴”了,看着好晕。。。
    unsigned shiftLeft=0;
    unsigned afterShift, tmp, flag;
    unsigned absX=x;
    unsigned sign=0;
    //special case
    if (x==0) return 0;
    //if x < 0, sign = 1000...,abs_x = -x
    if (x<0)
    {
        sign=0x80000000;
        absX=-x;
    }
    afterShift=absX;
    //count shift_left and after_shift
    while (1)
    {
        tmp=afterShift;
        afterShift<<=1;
        shiftLeft++;
        if (tmp & 0x80000000) break;
    }
    if ((afterShift & 0x01ff)>0x0100)
        flag=1;
    else if ((afterShift & 0x03ff)==0x0300)
        flag=1;
    else
        flag=0;
 
    return sign + (afterShift>>9) + ((159-shiftLeft)<<23) + flag;
}
/* 
 * float_twice - Return bit-level equivalent of expression 2*f for
 *   floating point argument f.
 返回 以unsinged表示的浮点数二进制的二倍的二进制unsigned型
 *   Both the argument and result are passed as unsigned int‘s, but
 *   they are to be interpreted as the bit-level representation of
 *   single-precision floating point values.
 *   When argument is NaN, return argument
 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
 *   Max ops: 30
 *   Rating: 4
 */
unsigned float_twice(unsigned uf) {
        unsigned f = uf;
    if ((f & 0x7F800000) == 0) //
    {
        //左移一位
        f = ((f & 0x007FFFFF) << 1) | (0x80000000 & f);
    }
    else if ((f & 0x7F800000) != 0x7F800000)
    {
        f =f + 0x00800000;
    }
    return f;
}

 

CSAPP 3e : Data lab

标签:ted   ice   tle   evel   float   否则   using   lease   oid   

原文地址:http://www.cnblogs.com/xihuyouyu/p/7521626.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!