CSAPP--DataLab

前言

在看完csapp第二章之后,上网找了配套的lab做,发现难度不是一般的大,附上实验链接:csapp实验网站,直接点Self-Study Handout就可以下载实验的资料,做实验之前要先把前面的README之类的先都看一遍,看一下实验要求

1.bitXor

//1
/* 
 * bitXor - x^y using only ~ and & 
 *   Example: bitXor(4, 5) = 1
 *   Legal ops: ~ &
 *   Max ops: 14
 *   Rating: 1
 */

题目条件:手动实现异或

x&y能够得到x、y都为1的位,(~ x & ~ y)能够得到x、y都为0的位,由于异或是两者相同取零,所以要对两者都取反,即~ (~ x&~y) & ~(x&y),可能还比较懵,举例说明一下

在这里插入图片描述

int bitXor(int x, int y) {
       return ~(~x&~y) & ~(x&y);
}

2.tmin

/* 
 * tmin - return minimum two's complement integer 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 4
 *   Rating: 1
 */

题目条件:返回TMin

TMin是符号位为1,其余位都是0,通过移位操作即可实现,1<<31是将第31位的1移到第一位,其余位用零填补

int tmin(void) {
 return 1<<31;
}

3.isTmax

/*
 * isTmax - returns 1 if x is the maximum, two's complement number,
 *     and 0 otherwise 
 *   Legal ops: ! ~ & ^ | +
 *   Max ops: 10
 *   Rating: 1
 */

题目条件:如果1是TMax,则返回1,否则返回0

TMin是符号位为1,其余位都是0,TMax是~(1<<31),x与TMax取异或,之后再取反,即可得到结果

int isTmax(int x) {
 return !(x ^ (~(1<<31)));
}

4.allOddBits

/* 
* allOddBits - return 1 if all odd-numbered bits in word set to 1
*   where bits are numbered from 0 (least significant) to 31 (most significant)
*   Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
*   Legal ops: ! ~ & ^ | + << >>
*   Max ops: 12
*   Rating: 2
*/

题目条件:如果奇数位值都为1,则返回1,否则返回0

可以通过掩码的方式,得到奇数位的值,同时将偶数位设置为0
将wall设置为0xAA,则前8位满足奇数位为1,偶数位为0,通过移位得到了wall=0xAAAAAAAA,将x与wall相与,得到x的奇数位的值,再将其与wall相异或,看奇数位是否仍为1
(这里存在一点疑问,本来我是想要直接将wall设置成0xAAAAAAAA,但是网上的答案都是通过移位实现的,感觉应该没什么区别吧…)

int allOddBits(int x) {
  int wall = 0xAA;
  wall = wall + (wall<<8) + (wall<<16) + (wall<<24)
  return !(wall ^ (x&wall));
}

5.negate

/* 
 * negate - return -x 
 *   Example: negate(1) = -1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 5
 *   Rating: 2
 */

** 题目条件:得到值的非**

根据csapp书上的公式,-x=~x+1即可求解

int negate(int x) {
 return (~x + 1);
}

6.isAsciiDigit

/* 
 * isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
 *   Example: isAsciiDigit(0x35) = 1.
 *            isAsciiDigit(0x3a) = 0.
 *            isAsciiDigit(0x05) = 0.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 15
 *   Rating: 3
 */

题目条件:如果x值在0x30到0x39之间,则返回1,否则返回0

与边界值进行比较,如果在0x30和0x39之间,左右两边的符号位都为0,向右移动31位之后仍为0,若是不满这个条件,则左右两边或的结果是全为1,取反之后得到零

int isAsciiDigit(int x) {
 return !(((x-0x30) >> 31) | ((0x39-x) >> 31));
}

7.conditional

/* 
 * conditional - same as x ? y : z 
 *   Example: conditional(2,4,5) = 4
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 16
 *   Rating: 3
 */

题目条件:如果x为真,返回y,如果不为真,则返回z

此题解法十分巧妙,将x化为布尔值,也就是说,x为0时,布尔值为0x00…00,x为其他值时,布尔值为0x00…01。
对x的布尔值取反加1,当x为0,val全为0,当x不为0时,val全为1
利用或运算,当val取1时,返回y,当val取0时,返回z

int conditional(int x, int y, int z) {
 int val = ~(!!x) + 1;
 return (val & y) | ( ~val & z);
}

8.isLessOrEqual

/* 
 * isLessOrEqual - if x <= y  then return 1, else return 0 
 *   Example: isLessOrEqual(4,5) = 1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 24
 *   Rating: 3
 */

题目条件:如果x<=y,则返回1,否则返回0

分情况讨论:
如果x、y符号位相同,则比较x-y的值即可
如果符号位不同,x符号位为0时返回0,x符号位为1时返回1

如果x和y符号位相同,则val1=0,若x<=y,则val2全1,若x>y,则val2全0
若符号位不同,则val1=1
利用位或表达式得到val2和val3的值

int isLessOrEqual(int x, int y) {
int val1 = (x << 31) + (y << 31);
int val2 = ! ((y + ~x + 1) >> 31) ;
int val3 = (x >> 31) & 1;
return (val1 & val3) | (~val1 & val2)}

9.logicalNeg

/* 
 * logicalNeg - implement the ! operator, using all of 
 *              the legal operators except !
 *   Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
 *   Legal ops: ~ & ^ | + << >>
 *   Max ops: 12
 *   Rating: 4 
 */

题目条件:实现x逻辑非

0的非是1,其他值的非都是0
如果x为0,x|x的符号位是0,向右移31位再加1能得到1,而其他的值与自身的复数进行或操作的符号位为1,向右移31位再加1能得到0

int logicalNeg(int x) {
 return (x | (~x+1)) >> 31 + 1;
}

—————————————————————————————
剩下的等之后再补充吧,感觉前面的还是挺难想的,先把题目放在这里了

10.howManyBits

/* howManyBits - return the minimum number of bits required to represent x in
 *             two's complement
 *  Examples: howManyBits(12) = 5
 *            howManyBits(298) = 10
 *            howManyBits(-5) = 4
 *            howManyBits(0)  = 1
 *            howManyBits(-1) = 1
 *            howManyBits(0x80000000) = 32
 *  Legal ops: ! ~ & ^ | + << >>
 *  Max ops: 90
 *  Rating: 4
 */
int howManyBits(int x) {
 return 0;
}

11.floatScale2

/* 
 * floatScale2 - 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 floatScale2(unsigned uf) {
 return 2;
}

12.floatFloat2Int

/* 
 * floatFloat2Int - Return bit-level equivalent of expression (int) f
 *   for floating point argument f.
 *   Argument is passed as unsigned int, but
 *   it is to be interpreted as the bit-level representation of a
 *   single-precision floating point value.
 *   Anything out of range (including NaN and infinity) should return
 *   0x80000000u.
 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
 *   Max ops: 30
 *   Rating: 4
 */
int floatFloat2Int(unsigned uf) {
 return 2;
}

13.floatPower2

/* 
 * floatPower2 - Return bit-level equivalent of the expression 2.0^x
 *   (2.0 raised to the power x) for any 32-bit integer x.
 *
 *   The unsigned value that is returned should have the identical bit
 *   representation as the single-precision floating-point number 2.0^x.
 *   If the result is too small to be represented as a denorm, return
 *   0. If too large, return +INF.
 * 
 *   Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while 
 *   Max ops: 30 
 *   Rating: 4
 */
unsigned floatPower2(int x) {
   return 2;
}

参考:
1.https://www.cnblogs.com/panhz/p/13450085.html
2.https://zhuanlan.zhihu.com/p/149689152

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值