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

Posted by Cww97 on 2016-03-27

版权声明:本文为博主原创文章,未经博主允许不得转载。原文所在http://blog.csdn.net/cww97 https://blog.csdn.net/cww97/article/details/50991331
折腾系统折腾了一星期。。。电脑变板砖无数次
昨晚立了个flag,要一晚写完这个实验题。。。。
//秋雨上次给我推荐了李宗盛的给自己的歌,
//一边听一边写写了一晚上。。。
写完发现,,,编译命令抽风,,,死活不给编译

这里写图片描述
这里写图片描述

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

编译用./dlc一出来30个error。。。尼玛,不合法,again
这里写图片描述
评测机还是比较良心的,给了WA的数据
这里写图片描述
终于过了
同学们加油,祝你们好运
下面贴的代码我把前面一大段废话给扔掉了,全是forbidden= =

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/* 
* 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;
}