深度懵逼计算机系统。。。DataLab。。
折腾系统折腾了一星期。。。电脑变板砖无数次
昨晚立了个flag,要一晚写完这个实验题。。。。
//秋雨上次给我推荐了李宗盛的给自己的歌,
//一边听一边写写了一晚上。。。
写完发现,,,编译命令抽风,,,死活不给编译
睡一觉,把elearning上面的实验代码重新下载一遍
然后把自己写的再填进去,,,编译能用了
估计是自己写的时候乱改,,,把btest给玩坏了
编译用./dlc一出来30个error。。。尼玛,不合法,again
评测机还是比较良心的,给了WA的数据
终于过了
同学们加油,祝你们好运
下面贴的代码我把前面一大段废话给扔掉了,全是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;
}