po主是在读大学生一枚,最近在学校中上ics课(introduction to computer science)并做配套的10个lab。特在此将lab内容以及我的思考解答过程与各位大神分享,希望能给真正想了解此课及这些实验之人一些帮助。若我的所言有不当之处,也请各位多多加以指正,也算是带一带我这个新人,我将感激不尽。
废话不多说,直入正题。
datalab 是初读此课的新手将要面临的第一个lab(po主当初花了很久才适应啊!),相对来说比较简单,主要是关于bits-level运算的一些题目。说实话,这个lab与整门课的方向比较脱节,很多bits-level的实现也确实更像智力测试题,不过既然有,便要攻克之。在做完之后,也确实对底层bits-level运算实现的理解有颇多加深。
Q1:(蓝色部分是lab要求,其中包括对要求实现的函数的解释、举例、可以用的bits-level操作、最多操作数以及分值,下面是我的函数实现)
很经典的bits-level实现绝对值运算,这也是我认为整个lab中唯一对以后实际应用(包括面试)有价值的运算。不用if操作的绝对值运算可以有效加快运算速度。
第一步取符号位,(正为0,负为111……1),第二步抑或操作对于正数相当于不变,对于负数相当于取反加一(即得相反数),从而完成了统一的取绝对值。
************************************************************************************************************************************************************************
Q2:
狄摩根定律,不解释。
************************************************************************************************************************************************************************
Q3:
boring but a little hard one.
题目要求是给出最高位和最低位,完成输出在最高位和最低位之间所有数字为1,其他位为0的一个mask。如题目所给例子即是bitMask(5,3)=(111000)2。
整体思路是构建两个mask,分别是从左端到最高位全部是1,剩下的为0的mask1,和从左端到最低位全部是1,其他是0的mask2,并将二者抑或,即可得到所求的mask。
而中间有一些小细节有其需要注意。
第一个是(exp<<highbit)<<1之所以不写成exp<<(highbit+1),是因为若highbit=31,此时左移(highbit+1)=32位,该操作不进行任何移位。
第二个是最后result&(exp<<lowbit)看似多余,实际上是防止(lowbit>highbit)的情况出现,并将其置0,使其符合题目要求。
************************************************************************************************************************************************************************
Q4:
分支选择,若x为真(x!=0)则表达式=y,若x为假(x==0)则表达式=z。
利用!操作(当x=0时!x=1,当x!=0时!x=0)容易得到。
************************************************************************************************************************************************************************
Q5:
不解释。。看不懂的话看看math logic吧。。
************************************************************************************************************************************************************************
Q6:
要求做一个mask所有偶数位都为1,奇数位都为0。
思路就是从01->0101->01010101->......
利用左移和or操作实现很简单。
************************************************************************************************************************************************************************
Q7:
相同两数抑或后为0,不同数抑或后不为0.利用此性质易解。
************************************************************************************************************************************************************************
Q8:
a little difficult.
第一步做一个mask记录x y是否相等
二三步做x-y
第四步要分xy符号相同和xy符号不同两种情况考虑,完成并取符号位。(正则为0,负则为1111……1)
第五步是将0 和1111……1都化成一位的0or1输出。
************************************************************************************************************************************************************************
Q9:
很简单,取符号位再少许进行运算输出就行。
************************************************************************************************************************************************************************
Q10:
利用只有0|-0 的符号位是0,其他x|-x符号位是1 即可求出。
************************************************************************************************************************************************************************
Q11:
若x是2的倍数,必有x&x-1=0.
另外x还需要大于0。(即是上面的isNegative的反)
将两个条件取和运算即可。
************************************************************************************************************************************************************************
Q12:
题目要求求出输入值2进制中最低位的1的所在位置。
很巧妙的运算,我是通过实验找的规律,具体证明我也无能为力,希望大神能帮忙指出!
************************************************************************************************************************************************************************
Q13:
利用其它操作符实现!操作。
思想就是压缩法,保留出不为1的位置,最后压缩到只有1位,结果是0则是表明该数之前全非1,结果是1表明该数必有某一位不为0(即该数非0)。
************************************************************************************************************************************************************************
Q14:
题目要求将每个byte位置颠倒。
思想很简单,就是利用一个mask(1111 1111)将每个byte取出来,之后再利用|操作把每个取出的byte放到应该放的位置。
************************************************************************************************************************************************************************
Q15:
终于到了最后一个大boss了!
诶话说这个题看起来好长啊。。肯定很难吧。。
仔细分析一下,其实就是要用1个加号实现3个数字相加。
初看可能没啥思路,但是仔细一想可以想到将三个数相加化成两个数相加,最应该直接想到的便是一个数记录无进位结果,另一个数记录进位情况。
三个数相加的无进位可以用抑或表示,x^y^z即可。
而进位情况则是两个数中,两个加数的某一位同为1时需要进位。
3个数的情况下,最多某一位相加是1+1+1 不需要考虑双重进位的情况,那么结果很明了了。
word1是无进位结果,word2代表进位情况(不要忘记最后左移一位!)
************************************************************************************************************************************************************************
data lab 完成!