zoukankan      html  css  js  c++  java
  • CSAPP 3e : Data lab

    /* 
     * 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;
    }
  • 相关阅读:
    5 TensorFlow入门笔记之RNN实现手写数字识别
    用python简便地抓取刘昊然的写真(17行代码)
    MFC实现简单飞机大战(含游戏声音)
    4 TensorFlow入门之dropout解决overfitting问题
    3 TensorFlow入门之识别手写数字
    2 TensorFlow入门笔记之建造神经网络并将结果可视化
    1 TensorFlow入门笔记之基础架构
    用python的turtle画分形树
    win10下安装TensorFlow(CPU only)
    python中math常用函数
  • 原文地址:https://www.cnblogs.com/xihuyouyu/p/7521626.html
Copyright © 2011-2022 走看看