西工大 计算机系统基础实验(04班) DataLab 2024 题意翻译+思路

写在前面

这是2024.04班的,不保证其它班/以后题目都一样,请额外注意喵!

部分思路源于其它大佬,感谢超级大神 @Fediory 叠的倾力帮助!另感谢 鸭子青蛙 等热心群友老师们。

思路比较简略,加油,我相信你。(况且我没法完全还原我推的思路了,只能尽量拿正确思路的启发你们一下)

本文目前作为实验报告被提交,提交信息中含有一段随机值,其SHA1摘要为:4d3d77fd6fb2951a68d9b0ec71f75c91ea0213ba


圆括号代表我对难度的评分,方括号数字代表最优解个数,加号+代表优化难度。

*是优化提示,!是优化解答,没有完整标答,多多思考喵。

最重要的提示:加法融合了溢出等多种逻辑,与各类优化相关

变量名全是错的😈️我故意的😡自己按照思路写!copy不好!

实在不会请善用各类交流群捏。

打榜,爽!

题意整理

  1. LsbZero —— 将最低位设为0
  2. Tmax —— 返回补码数字的最大正数
  3. UpperBits —— 生成一个高n位为1的掩码 ( 0 ≤ k ≤ 32 ) (0 \leq k \leq 32) (0k32)
  4. fitsBits —— x能否存进n位补码里?能返回1,不返回0
  5. isNegative —— n < 0
  6. isNotEqual —— x != y
  7. mul3div2 ——n * 3截断,然后除2,向零取整
  8. bitMask —— 生成一个掩码,二进制从low到high位是1(两端均含)(位序数从右边起,从0起)
  9. isAsciiDigit —— 字符编码x是不是ASCII的数字?(数字的编码 0x30 ≤ n u m ≤ 0x39 \text{0x30} \leq num \leq \text{0x39} 0x30num0x39
  10. isNonNegative —— n >= 0
  11. logicOr —— x || y
  12. rewpw2 —— x % (1<<n) 取余数。取余要求余数要么是0,要么和被除数的符号相同。
  13. satMul3 —— 类似16,但是这次计算的是乘3
  14. logicNeg —— 不使用!来实现!
  15. float_f2i —— 用unsigned int uf 存了个 ieee754 32位浮点数 的二进制表示,请把它向下取整转成整数。
  16. satAdd —— 计算a + b,如果结果为正但是太大溢出了,返回0x7fff ffff,负溢出了则返回0x8000 0000。
  17. tc2sm —— 计算原码。

0. 好用的板子

请尽可能地理解这些模板的原理。

部分板子源于大佬们。

这些板子的推导大部分是基于“注意到”的,很难说明它们到底是怎么想出来的。

将低n位置0

a & ~... 比较标准但是有点麻烦
a >> n << n n大于8时很好用+省符号

相反数

(~n + 1) 即-n,补码不解释。

优化提示:取负数常数的时候请使用 (~(n-1))并且提前求出 n-1 。

取01

我们发现符号表里有个!,逻辑非,好耶。

复习一下:在C语言中没有所谓的布尔类型,!生成的False总是0,True总是1;0总是视作False,大部分机器把非零都视作True。少部分机器<0也视作False。在其他地方用出bug的时候记得想一想这个。

n = 0的时候!n = 1,!!n = 0
n不为0时!n = 0,!!n = 1

记住 !!n

符号相关板子

sign = a >> 31 —— 提取符号,如果a为负,得到-1或全1;如果a为正,得到全0。算术右移。
(a + sign) ^ sign —— 乘以符号,可以用来取绝对值。原理:sign为-1就减1然后异或全1取反,sign为0就没用。

选择器板子

(a & sign) | (b & ~sign)——sign 为-1时返回a,为0时返回b


喜欢独立思考的别往下看了嗷

1. LsbZero (0/5) [2]

要求:将最低位设为0。

可用方法:

a & ~1;
a >> 1 << 1;

2. Tmax (0/5) [2]

要求:返回补码最大值,即2147483647 0x7fff ffff

用最高位为1取反即可。

~(1<<31);

3. UpperBits (1/5) [6]

要求:生成一个高k位为1的掩码。 ( 0 ≤ k ≤ 32 ) (0 \leq k \leq 32) (0k32)

注意:k可能为0也可能为32,为0要特殊处理,32没法移动,需要处理这两种边界情况。

既然高k位为1,考虑用符号右移从 1 << 31拉出若干个 1 吧。>>1就有两个1了,所以我们需要k - 1个,但是没有负数和减号怎么办捏,用取反~0得到-1即可。

1 << 31 >> (k + ~0)

但是我们发现k = 0的时候会出问题,我们就想,如果k=0的时候左边那个1是0就好了,但是k最低位并不总是1,不能用&1🤔

那就!!n取1板子。

那么

!!k << 31 >> (k + ~0);

收工。

4. fitsBits (3/5) [6]

要求:判断a能不能存在n位补码里。

首先根据课本可知,扩展大小并在左边添加和m个符号位相同的bit不会改变表示的数。(证明我就不写了,好好看课本!)

同理,从左边删除m个相同bit也不会改变表示的数。

换言之,如果能用n个bit表示,那么,从右起数n-1个bit,不管它们,其它的bit必须是相同的bit,当然,这些bit肯定和原来int的符号位一样。减一是保留符号位。

嗨嗨,还是符号右移,我们直接 a >> n - 1 把 n - 1 个bit挤掉,然后和 a >> 31 比较是否相等。

比较相等请参见 6 isNotEqual 捏

5. isNegative (0/5) [2]

要求:n负数时返回1。

提取符号之后,正是全0、负是全1,容易看出&1取低位即可。

6. isNotEqual (1/5) [3]

要求:a != b返回1,a == b 返回 0

异或可能大家不熟悉,我再讲一次:a b某位不同时,该位结果为1,相同时结果为0。

那么容易想到,a ^ b在a b相同时返回全0,否则返回必带1,然后!!板子即可。

7.mul3div2 (1/5) [6]

要求:返回 n * 3 / 2 的结果(并且符合机器乘除的行为)

请注意,除2不能完全等价于>>1,除2会向0取整,但是>>1会向下取整!((-1)/2 为 0,-1 >> 1 为 -1!!!)

所以很简单我们给乘积为负数的加个1再右移即可。(-2 + 1 => -1,-1>>1 =>-1,-1+1=>0,0>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值