文章目录
Lab01 DataLab
1. bitXor
要求:
- x ^ y using only ~ and &
- max ops: 14
- rating: 1
题解:
x ^ y
将x和y看成集合A和B
x ^ y其实为A 并 B - A 交 B
x | y 为 A 并 B
x & y 为A 交 B
(x | y) & (~(x & y)) A 并 B - A 交 B
x | y <=> ((x) & (~y))
-
((x) & (~y))
-
的运算级高于
(x & ~y)
(x & ~y) & ~(x & y)
int bitXor(int x, int y) {
return ~(~x & ~y) & ~(x & y);
}
2.tmin
要求
- return minimum two’s complement integer (返回最小的二进制补码)
- legal ops: ! ~ & ^ | + << >>
- max ops: 4
- rating: 1
题解:
32位
x_{32} x_{31} … x_{1}
- x_{32} * 2 ^ {32-1} + x_{31} * 2 ^ {31 -1} + x_{30} * 2^{30 - 1} … + x_{i} * 2^{i-1} + … + x_1 * 2^{1-1}
故当 x_{32} 为1, 其余为0的时候最小
int tmin(void){
return 1<<31;
}
3. isTmax
要求
- return 1 if x is the maximum, two’s complement number, and 0 otherveise
- Legal ops: ! ~ & ^ | +
- max ops: 10
- rating: 1
题解:
maximum 0x7FFFFFFF
0111 1111 1111 1111 1111 1111 1111 1111
~maximum == maximum + 1
1111 1111 1111 1111 1111 1111 1111 1111
如何用 & … 来实现
if…else
if(A)
return B
else
return C
A : x 是否为y --> 1 or 0
~A + 1 全1 全0
(~A + 1) & B | (A + 1) & C
如果x为Tmin
return 0
else return !(~x ^ (x +1))
A: !(~x)
A & C | ~A & B <=> ~A & B
int isTmax(int x) {
int A = !(~x);
int B = !(~x ^ (x + 1));
int C = 0;
return A & C | ~A & B ;
}
4. 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)
- Legal ops: ! ~ & ^ | + << >>
- max ops: 12
- rating : 2
题解:
1010 1010 1010 1010 1010 1010 1010 1010
0 - 255
8位8位的比
0xAA
int allOddBits(int x) {
int a = 0xAA;
a = a | (a << 8) | (a << 16) | (a << 24);
return !((a & x) ^ a)
}
5. negate
要求
- return -x
- legal ops: ! ~ & ^ | + << >>
- max ops: 5
- rating: 2
题解
求一个数的相反数
Tmin的相反数是无法表示的
不考虑Tmin
x + (-x) = 0
将最高位摘出来, 此时的x 和 -x 都只有低31位
- 2 ^ 31 + x_low31+ (-x)_low31 = 0
2^31 = x_low31 + (-x)_low31
int negate(int x) {
return ~x + 1;
}
6.isAsciiDigit
要求
- return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters ‘0’ to ‘9’)
- Legal ops: ! ~ & ^ | + << >>
- max ops: 15
- rating: 3
题解
x >= 0x30
int low = 0x30, high = 0x39;
int A = !((x + (~low + 1))>>31);
int B = !((~x + 1 + high)>>31);
return A & B;
int isAsciiDigit(int x) {
int low = 0x30, high = 0x39;
int A = !((x + (~low + 1))>>31);
int B = !((~x + 1 + high)>>31);
return A & B;
}
7.conditional
要求
- x ? y : z
- legal ops: ! ~ & ^ | + << >>
- max ops: 16
- rating: 3
题解
if(A)
return y
else return z
A: x是否为非0
A : !!x
~A + 1
0 -> 全0
1 -> 全1
()~A + 1) & y
int conditional(int x, int y, int z) {
int A = !!x;
A = ~A + 1;
return (A & y) | (~A & z) ;
}
8. isLessOrEqual
要求
- if x <= y then return 1, else return 0
- legal ops: ! ~ & ^ | + << >>
- max ops: 24
- rating: 3
题解
同号
比较低31位
不同号 正的大
if(A)
return B
else
return C
A: x >>31 ^ y >>31 是否为不同号
A & C | !A & B
C : x >> 31
B: y - x >= 0
(y + ~x + 1)
0x10000000000
不要 (y + (~x + 1)) wrong
int isLessOrEqual(int x, int y){
int A = (x >> 31 & 1) ^ (y >> 31 & 1);
int C = (x >> 31 ^ 1);
int B = !((y + ~x + 1)>>31 & 1);
return (A & C) | (!A & B);
}
9.logicalNeg
要求
- implement the ! operator, using all of the operators except !
- Legal ops: ~ & ^ | + << >>
- max ops: 12
- rating: 4
题解
0 区别于其他数相反数是它本身啊
还有一个特例Tmin 也是它本身
看最高位
x -x |
Tmin 1 1 1
0 0 0 0
other 1 /0 0/1 1
((x | (~x + 1)) >> 31) + 1
int logicalNeg(int x) {
return ((x | (~x + 1)) >> 31) + 1;
}
10.howManyBits
要求
- return the minimum number of bits required to represent to represent x in tow’s complement
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 90
- Rating: 4
题解
x 为正数
为1的最高位到0位 + 1符号位为0
x 为负数
高位连续1的最低位到0位 == 为0的最高位到0位 + 1
进行取反操作
为1的最高位到0位 + 1
找为1的最高位
从高位开始找
- 检查31位-16位(x >> 24)
- 如果存在1, 就在31位到16位 (至少要16位)
- 对x进行处理一下 x >>= 16 , 此时就计算0-15位上为1的最高为,和下面的情况相同了
- 如果不存在,就在0位到15位
- … 之后就类似分析, 折半搜索就好了
- 如果存在1, 就在31位到16位 (至少要16位)
if x为负数
x = ~x
A: (x>>31 & 1) x 是否为负数
A = ~A + 1; // 0 -> 全0 1 -> 全1
x = (A & ~x) | (~A & x);
31 - 16 16 (31 - 0)
15 - 8 8 (15 - 0)
7 - 4 4 (7 - 0)
3 - 2 2 (3 - 0)
1 - 1 1 (1 - 0)
0 -0 1 (0 - 0) terminate
0000 0000 0000 0000 0000 0000 0000 0000
4 8
011000
int howManyBits(int x) {
int b0, b1, b2, b4, b8, b16;
int A = x>>31;
x = (A & ~x) | (~A & x);
b16 = (!!(x>>16))>>4;
x >>= b16;
b8 = (!!(x>>8))>>3;
x>>=b8;
b4 = (!!(x>>4))>>2;
x>>=b4;
b2 = (!!(x>>2))>>1;
x>>=b2;
b1 = (!!(x>>1));
x >>= b1;
b0 = x;
return b0 + b1 + b2 + b4 + b8 + b16 + 1;
}
11.floatScale2
要求
- return bit-level equivalent of expression 2 * f for floating point argument f. (将一个浮点数 x 2,这个浮点数的比特形式存在一个unsigned类型中)
- 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.
- legal ops: Any integer/unsigned operations incl. || , &&, also, if, while
- max ops: 30
- rating 4
题解
(-1)^s * 2 ^ E * M
规格数(E不全为0)
M = 1.frac
E = exp - bias
非规格数(E全为0)
M = 0.frac
bias = 2^7 - 1
E = 1 - bias
|31(s) | 30 - 23(exp) | 22 - 0(frac)|
x2
规格数
exp + 1
(-1)^s * 2 ^ E * M -----> (-1)^s * 2 ^ (E + 1) * M
非规格数
M << 1
0000 0000 1000 0000 0000 0000 0000 0000
10
unsigned floatScale2(unsigned uf) {
unsigned E = (0x7F800000 & uf) >> 23, M = 0x7FFFFF & uf;
if(E) {
if(E == 255) return uf;
E += 1;
}else {
M<<=1;
}
return (uf & 0x80000000) | (E<<23) | M;
}
12.floatFloat2Int
要求
- return bit-level equivalent of expression (int) f for floating point argument f.
- Arguement is passed as unsigned int, but it is to be interpretered 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 interger/unsigned operations incl. ||, &&, also if, while
- max ops: 30
- rating: 4
题解
|(s)|||
1.M
<< 23
exp - 127
exp为全0 -> 非规格数 -> 小数 -> 0 (int)
exp不全为0
->规格数
1.M
2^(exp - 127) * 1.M
-> exp < 127 -> 小数 0
= 127 + 31 = 158 return
-2^31
31= exp - 127
exp = 158
158 = 128 + 16 + 8 + 4 + 2
1100 1111 0000 0000 0000 0000 0000 0000
0xcf000000
int floatFloat2Int(unsigned uf) {
int E = (uf & 0x7F800000) >23, M = (uf & 0x7FFFFF), m, f;
if(E < 127) return 0;
if(E > 157) return 0x80000000;
M = M | (1<<23);
m = (E - 150);
if(m >= 0) M<<=m;
else M >>= -m;
f = ~(uf>>31) + 1;
return (f & (~M + 1)) | (~f & M);
}
13.floatPower2
要求
- return bit-level equivalent of the expression 2.0^x for any 33-bit interger x
- The unsigned value that is returned should have the idenical bit representation as the single-precision floating-point number 2.0^x.
- if the result is too small to be represent 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
题解
2.0 * x
(-1)^s * 2^x * 1
E = x = exp - 127
M = 1 = 1.frac
exp = 127 + x
127 + x > 0
x > -127 规格数
127 + x < 255
x < 128
-149 <= x <= -127 非规格数
frac = frac | (1 << (23 + 127 + x))
-127 < x < 128 规格数 exp = 127 + x
x >= 128 return +INF
if(x >= 128) return 0x07F800000;
else if(x > -127) exp = 127 + x;
else if(x >= -149) return frac = frac | (1 << (22 - x + 127);
else return 0;
unsigned floatPower2(int x) {
int exp = x+127, frac = (1<<(149-x)), flag = x & 0x80000000;
if(x > 128) return 0x7F800000;
else if(x > -127) return flag | (exp << 23);
else if(x >= -149) return flag | frac;
else return 0;
}