深度懵逼计算机系统。。。DataLab。。

折腾系统折腾了一星期。。。电脑变板砖无数次
昨晚立了个flag,要一晚写完这个实验题。。。。
//秋雨上次给我推荐了李宗盛的给自己的歌,
//一边听一边写写了一晚上。。。
写完发现,,,编译命令抽风,,,死活不给编译

深度懵逼计算机系统。。。DataLab。。_第1张图片

睡一觉,把elearning上面的实验代码重新下载一遍
然后把自己写的再填进去,,,编译能用了
估计是自己写的时候乱改,,,把btest给玩坏了

编译用./dlc一出来30个error。。。尼玛,不合法,again
深度懵逼计算机系统。。。DataLab。。_第2张图片
评测机还是比较良心的,给了WA的数据
深度懵逼计算机系统。。。DataLab。。_第3张图片
终于过了
同学们加油,祝你们好运
下面贴的代码我把前面一大段废话给扔掉了,全是forbidden= =

/* * CS:APP Data Lab * * <陈伟文 10152510217> * *================2016.3.27=13:29================== * * 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);
}//return x&y 
/* * getByte - Extract byte n from word x * Bytes numbered from 0 (LSB) to 3 (MSB) * Examples: getByte(0x12345678,1) = 0x56 * Legal ops: ! ~ & ^ | + << >> * Max ops: 6 * Rating: 2 */
int getByte(int x, int n) {
    return (x>>(n<<3))&0xff;
}
/* * 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) {
    //直接return x>>n 负数会挂
    int t=(1<<31)&x;//取符号位 
    t=((t>>n)<<1); 
    t=~t; //符号位前一位清0 
    return (x>>n)&t;
}
/* * bitCount - returns count of number of 1's in word * Examples: bitCount(5) = 2, bitCount(7) = 3 * Legal ops: ! ~ & ^ | + << >> * Max ops: 40 * Rating: 4 */
int bitCount(int x) {//统计一个数有多少个二进制1 
    //http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel 
    //没怎么懂原理,弄了几个数据手动模拟了一下,,
    //刚开始的x可以理解为每一位二进制下有多少个1(非0即1) 
    //然后每一步大概就是合并两段的1的个数 
    //最后全堆到前16位 
    //x=(x+(x>> 1))&(0x55555555);// 01010101 01010101 01010101 01010101
    //x=(x+(x>> 2))&(0x33333333);// 00110011 00110011 00110011 00110011 
    //x=(x+(x>> 4))&(0x0f0f0f0f);// 00001111 00001111 00001111 00001111 
    //x=(x+(x>> 8))&(0x00ff00ff);// 00000000 11111111 00000000 11111111 
    //x=(x+(x>>16))&(0x0000ffff);// 00000000 00000000 11111111 11111111
    //如果有神犇能看懂请教我 
    //fuck,.,,,,Illegal constant (only 0x0 - 0xff allowed)
    int tmp=(((0x01<<8|0x01)<<8|0x01)<<8|0x01)<<8|0x01;
    int val=tmp&x;//检测 x 的 0,8,16,24 位是否为 1
    val+=tmp&(x>>1);//检测 x 的 1,9,17,25 位是否为 1
    val+=tmp&(x>>2);//...
    val+=tmp&(x>>3);
    val+=tmp&(x>>4);
    val+=tmp&(x>>5);
    val+=tmp&(x>>6);
    val+=tmp&(x>>7);//检测 x 的 7,15,23,31 位是否为 1
    val+=(val>>16);//将 val 的高 16 位加到低 16 位上
    val+=(val>>8);//再将 val 的高 8 位加到低 8 位上
    return val&0xff;//保留 val 的最低 byte 信息 为最终结果
}
/* * bang - Compute !x without using ! * Examples: bang(3) = 0, bang(0) = 1 * Legal ops: ~ & ^ | + << >> * Max ops: 12 * Rating: 4 */
int bang(int x) {//return !x
    int t=~x+1;
    //x=0时,t=0; 
    //x>0时,x符号位=0,t的符号位=1;
    //x<0时,x符号位=1,t的符号位=0;
    // x=0时x|t的符号位 =0,else =1
    return (~((x|t)>>31))&1;
}
/* * tmin - return minimum two's complement integer * Legal ops: ! ~ & ^ | + << >> * Max ops: 4 * Rating: 1 */
int tmin(void) {//return INT_MIN 
    //一种比较好理解的方式是:溢出从最大跌倒最小(这是我自己yy的)
    //记住机器寸的都是补码,补码公式。。。gg
    //补码=0x80000000时最小(why啊why啊啊啊啊啊) 
    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 t=!!(x>>31);//符号位 
    //x>0时,需要给最高位留个0空着,所以右移n-1位 
    return ((!t)&(!(x>>(n+~0))))|(t&!((~x)>>(n+~0)));
    // >=0 <0
}//= =!此题极有可能WA !...果然WA了。。 
//(-2147483648[0x80000000],1[0x1]) failed...
//...Gives 1[0x1]. Should be 0[0x0]
/* * 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) {//return x/(2^n)
    //x/(1<<n), x>>n,,,负数有点麻烦,如果移动的位里有1,则结果+1 
    int t=!!(x>>31);//取符号 
    int tmp=(1<<n)+~0;
    int tt=tmp&x;//取后n位 
    return (x>>n)+((!!tt)&t);//取后n位是否有数 
}
/* * negate - return -x * Example: negate(1) = -1. * Legal ops: ! ~ & ^ | + << >> * Max ops: 5 * Rating: 2 */
int negate(int x) {//return -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>0 return 1;else 0 
    //本想return !!!(x<<31),蛋疼的是x==0的时候 
    int t=!!(x>>31);//取符号位 
    return (!t)&(!!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) {//return x<=y
    //本想直接return !!!((y-x)>>31),,没考虑溢出 
    //x*y>=0时,不会溢出,
    //else 若x>0.则y<0,return 0;
    // 若x<0.则y>0,return 1;
    int tx=!!(x>>31);
    int ty=!!(y>>31);
    int t=!!((y+(~x+1))>>31);//y-x 
    return ((!t)&(!(tx^ty)))|((tx^ty)&tx);
}
/* * ilog2 - return floor(log base 2 of x), where x > 0 * Example: ilog2(16) = 4 * Legal ops: ! ~ & ^ | + << >> * Max ops: 90 * Rating: 4 */
int ilog2(int x) {//return floor(log base 2 of x)
    /*int M=1,t=0; *while (M<=x)M<<=1,t++; *return --t //no loops,,,fuck */
    //二分法,每次取前半段,看是否有1存在。32=1<<5,故5次二分 
    int t,s1,s2,s3,s4,s5;
    t=!!(x>>16);//if 前16位有1 则t=1,else =0 1
    s1=t<<4;    // 16 0 
    x>>=s1;         // 取左半边 , 右半边 
    t=!!(x>>8);     //以此类推。。。。 三句一循环 2
    s2=t<<3;
    x>>=s2;
    t=!!(x>>4);     //loop again 3 
    s3=t<<2;
    x>>=s3;
    t=!!(x>>2);     //again 4
    s4=t<<1;
    x>>=s4;
    t=!!(x>>1);     //end 5
    s5=t<<0; 
    return s1+s2+s3+s4+s5;
}
/* * 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) {//return -uf 
    unsigned ans=uf^0x80000000;//符号位取反 
    unsigned tmp=uf&0x7fffffff;//符号位扔掉 
    if (tmp>0x7f800000)return uf;//not a number
    return ans;//为什么是上面一行那个数我也不知道。。。 
}
/* * float_i2f - Return bit-level equivalent of expression (float) x * Result is returned as unsigned int, but * 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 s=x&(1<<31);//取符号位
    int i=30;//*初始化 i 为 30*
    int exp=(x>>31)?158:0;//初始化 exp
    int frac=0;//用来保存尾数10
    int delta;//保存精度
    int frac_mask=(1<<23)-1;//frac_mask 低 23 位全 1,高 9 位全 0
    if (x<<1){//如果 x 不为 0 也不为-2^31
        if(x<0)x=-x;//x=|x|
        while(!((x>>i)&1))i--;//x 最高位 1 权重为 i(编号从 0 开始)
        exp=i+127;//偏置指数 e=E+Bias,Bias=127
        x=x<<(31-i);//扔掉 x 前面的 0
        frac=frac_mask&(x>>8);//frac 取尾数(取 x 的高 23 位)
        x=x&0xff;//保留 x 的末 8 位,将处理的精度
        delta=x>128||((x==128)&&(frac&1));//处理精度,四舍五入
        frac+=delta;//加上精度
        if(frac>>23){//如果尾数溢出
            frac&=frac_mask;//取尾数的后 23 位
            exp+=1;//产生进位
        }
    }
    return s|(exp<<23)|frac;//返回最后结果
}
/* * float_twice - Return bit-level equivalent of expression 2*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 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 s=uf&(1<<31); //取符号位 
    int exp=(uf>>23)&0xff; //取阶码 
    int frac=uf&((1<<23)-1); 
    if((exp^0xff)){ //如果阶码部分不为 255 
        if(!exp){ frac<<=1;} //阶码部分不为 0将尾数左移一位即可 
        else{ //如果阶码为 0 
            exp++; //将阶码加 1 
            if(exp==255)frac=0; //所得阶码为 255,将尾数设置为 0,表示无穷大 
        } 
    }//省略 else 情况,即 uf 为 NaN 
    return s|(exp <<23)|frac;
}

你可能感兴趣的:(计算机系统)