因为我不是计算机专业的,可以这么说,我是民计(类似民科),所有计算机相关的内容都是自学的,在看 CSAPP 第二章的时候看得我是异常得痛苦,虽然我能看懂,但是我认为我对数据表示这一块不是很感兴趣,所以看起来有点难受,索性我直接采用探索性学习法,我决定不再看第二章,直接去做第二章的作业,以及DataLab,而我将在探索中学习到这些知识,现在这篇文章是我做DataLab的记录。

注:这篇文章句子很乱完全就是我自己的思考过程,没有整理

bitXor(x,y)

 1/* 
 2 * bitXor - x^y using only ~ and & 
 3 *   Example: bitXor(4, 5) = 1
 4 *   Legal ops: ~ &
 5 *   Max ops: 14
 6 *   Rating: 1
 7 */
 8int bitXor(int x, int y) {
 9  
10}

只用~和&实现异或运算, 我们首先得搞懂异或运算是什么:不同为 1,相同为0

aba^b
011
101
110
000

所以我们可以这么说

异或运算 是:a b 至少有一个1,并且a b不能同时为1

我们又知道

且运算是 :a b 同时为 1

或运算是:a b 至少有一个1

那么异或就可以表示为 (a | b) & ~(a & b)

但是题目只让我们使用 ~ and &

所以我们需要用 ~ & 表示 |

既然我们要替换掉 |

我们仔细看看它的真值表

aba|b
011
101
111
000

我们还可以这么描述 | 运算 :a b 不同时为 0

而我们注意到 且运算是 :a b 同时为 1

我们尝试将 a b 同时为 1 变为 a b 不同时为 0

我们尝试给 (a & b) 前面加个 ~ 变成了 ~(a & b) 这表示的是 a b 不同时为 1

接近了 我们想想 a b同时为 0 怎么表示,且运算说的是 a b 同时为 1

那如果 a 和 b 此时为 0 则 ~a 且 ~b 就是 1了

所以 最终 ~(~a & ~b) 表示为 a b 不同时为 0

所以最终异或就可以表示为 ~(~a & ~b) & ~(a & b)

 1/* 
 2 * bitXor - x^y using only ~ and & 
 3 *   Example: bitXor(4, 5) = 1
 4 *   Legal ops: ~ &
 5 *   Max ops: 14
 6 *   Rating: 1
 7 */
 8int bitXor(int x, int y) {
 9    return ~(~x & ~y) & ~(x & y);
10}

同理~(~a | ~b)可以表示 &

由此我们可以总结出德摩根律

$$ \neg (A\wedge B) = \neg A\vee \neg B $$$$ \neg(A\vee B) = \neg A \wedge \neg B $$

tmin()

1/* 
2 * tmin - return minimum two's complement integer 
3 *   Legal ops: ! ~ & ^ | + << >>
4 *   Max ops: 4
5 *   Rating: 1
6 */
7int tmin(void) {
8
9}

我们观察一下二进制转补码的公式

$$ B2T_w(\vec{x}) = -x_{w-1}2^{w-1}+\sum_{i=0}^{w-2}x_i2^i $$

可以看到 $\sum_{i=0}^{w-2}x_i2^i\ge0$ 如果这一项等于0 则函数值最小,即从 $w-2$ 到 $i$ 位上 $x_i$ 都为 0

所以我们需要构造出来这么一个数,第 $w-1$ 位 是1 其他位都是 0,我们可以这么构造 0x1«(w-1)

所以

1/* 
2 * tmin - return minimum two's complement integer 
3 *   Legal ops: ! ~ & ^ | + << >>
4 *   Max ops: 4
5 *   Rating: 1
6 */
7int tmin(void) {
8    return 1 << 31;
9}

isTmax(x)

 1/*
 2 * isTmax - returns 1 if x is the maximum, two's complement number,
 3 *     and 0 otherwise 
 4 *   Legal ops: ! ~ & ^ | +
 5 *   Max ops: 10
 6 *   Rating: 1
 7 */
 8int isTmax(int x) {
 9 
10}

这题让我们判断 x 是否是 TMax ,

我们稍微改一下题目,如果仅仅不能用if,以及各种条件判断语句,可以使用 == 则可以这么写

1int isTmax(int x){
2   return x == INT_MAX;
3}

但是现在的问题是我们不能用 INT_MAX 也不能用 ==,我们需要用题目给的运算符以及已知量 x 构建出另一个式子,

我们对 x==INT_MAX进行改写,写成x == TMax,这样做是因为我们现在不知道TMax ,TMax是一个未知量,

而我们需要通过一系列等价变形将 x == TMax 变为两边只包含x和运算符的式子,由于x也是变量,最终如果这个式子为真当且仅当 x 的值为TMax,所以我们假设这个式子一直为真,即 x 的值为TMax,我们的目标就是将 x==TMax 变为两边只包含x和运算符的式子,第一个想到的式子就是 TMax + 1 = TMin,这样式子就变为 x+1 == TMin ,然后再利用 TMin == -TMin这个性质,有 x+1 == -(x+1),但是注意 0 == -0 也有这个性质,所以我们需要判断 (x+1)!=0

所以我们可以写成这样一个式子 : ((x+1) == -(x+1)) & ((x+1)!=0)

现在我们唯一要做的就是将 “-”,"==","!=“用题目给的运算负表示,我们知道异或的性质:A^A = 0,(A^B)!=0 ,我们也知道在c语言中 !a 表示 :如果a为0则 !a 为 1,如果 a 不为 0 则 !a 为 0,所以我们可以用!(a^b)表示 a==b这个运算,可以用!!(a) 表示 a!=0这个运算,而根据补码的性质 -x = ~x+1

所以最终我们可以得到:!((x+1) ^ (~(x+1)+1)) & !!(x+1)

 1/*
 2 * isTmax - returns 1 if x is the maximum, two's complement number,
 3 *     and 0 otherwise 
 4 *   Legal ops: ! ~ & ^ | +
 5 *   Max ops: 10
 6 *   Rating: 1
 7 */
 8int isTmax(int x) {
 9 	return !((x+1) ^ (~(x+1)+1)) & !!(x+1);
10}

待更新