目录
前言
在看完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