CSAPP data实验

前前后后做了大概一个星期,大致是周末多弄点,平时少弄点。最近疫情迭起又搞得图书馆的卷王和我抢自习室,然后又是PCR啥的打乱了正常生活秩序,希望疫情早日消失吧。

其他的函数都还好,就这个howmanybits搞得我焦头烂额。
排核酸的时候我在想,睡觉的时候我在想,怎么也找不出在90次位操作以内的解法,离谱,还是我太菜了。

简单记下当初的想法:

  1. bitXor
    用取反和位与实现异或,数字逻辑题
    记 横杠 为[]
    x ^ y
    = x[y] + [x]y
    = [[x[y]][[x]y]] (德摩根律)
    [num] = ~num
    故有 x ^ y = ((x & (~y)) & ((x) & y)))

level1, 问题不大

  1. tmin
    题目假定了是32位,常数在0~256范围内就行,那么直接 1<<31 就行了
    暂时没想出通用于16位int的方法

  2. isTmax
    如果是tmax,加1就和tmin异或得0了,结果再非一下

  3. allOddBits
    符合这个条件的只有一个数,用给定的操作和范围内的常数把这个数得到,
    然后异或一下就差不多了

  4. negate
    书上给过的补码规律: -x = ~x + 1

  5. isAsciiDigit
    这个是用位运算判断一个数是否在一个给定的范围……
    首先确定高位都是0,然后确认低位第二个字节是0011,最后是画的卡诺图把低4位情况判断一下
    最后用或非四个判断结果作为返回值

  6. conditional
    用!x把判断变量的范围限制在0或1,然后negate一下作掩码

从这里开始画风开始变化
8. isLessOrEqual
按两个数的符号位分情况讨论:
(1) x是正数, y是负数
(2) x是负数, y是正数
(3) x是正数, y是正数
(4) x是负数, y是负数

(1)(2)情况根据符号位可以直接得结果:
一个变量记一下是不是这种情况,另一个记一下是(1)还是(2)
(3)(4)情况可以直接减而不用担心溢出
然后和0异或就差不多了

9.logicalNeg
这个是灵光一现,不用32位逐位或一遍
如果x非0,那么x和-x总有一个符号位是1
用这个判断就行了

10. howManyBits
(暂时没想出来)
90次运算,对应30位 * 3次
至少要用1位,最后一位不用判断
符号位也要通过某种手段处理
剩下30位每位也才允许3次操作

(1)想过异或来帮我判断:
x左移一位,然后和x异或,出来的结果中
只要知道第一个1出现的位置,就能知道答案

但是要>>,!,+ 31次,超了
而且需要!两次加起来……

(2)想过直接右移判断
每次右移,非0就加1,直到数为0或-1为止
判断数为0或-1成本太大
而且还是需要非两次
而且还需要重复31次

G

就算只有正数,也想不到……

11-12-13. float运算
这里要求松多了,几乎可以用除函数调用、类型转换之外的任意操作,包括条件判断
所以主要就是把符号位、阶码、小数部分取出来,然后分情况细致讨论即可,和howmanybits比起来是毛毛雨啦

posted @ 2022-03-12 18:08  浅蓝星  阅读(63)  评论(0编辑  收藏  举报