1、bitXor
/* 1* bitXor - x^y using only ~ and & * Example: bitXor(4, 5) = 1 * Legal ops: ~ & * Max ops: 14 * Rating: 1 */
其实是数学公式
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 */
思路: 最小值为1000 0000 0000 0000 0000 0000 0000 0000,所以我们可以让1 << 31位。
* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 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 */
思路:
最大值 0111 ... 1111,假设a = maximum, 那 a + 1 = 1000 ... 0000,取反之后就等于a,可以做个&运算,如果相等就返回1,不相等就返回0。但是也有个特例,假设a = 1111 .... 1111, a + 1 = 0000 .... 0000。那再做&运算也是返回1, 所以我们还得加个条件: a + 1 = 0,那我们规格化一下 !!(a + 1)还是 0,然后和 !!(a + 1) ^ 0x0),因为不是maximum就返回0,他如果和0一样正好返回0,和要求一样。
int isTmax(int x){
return (!((~(x + 1)) ^ x)) & (!!(x + 1) ^ 0x0));
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 */ int allOddBits(int x) { return 2;
意思就是奇数为1,则返回1,否则返回0
思路:
四位 1010 满足奇数为1,所以 定义 int A = 0xA。然后左移四位,
int AA = A << 4 = 1010 0000。然后让 A | AA = 0000 1010 | 1010 0000 = 1010 1010
依此类推 ,定义 AAA (左移8位) AAAA(左移16);然后 !((x & AAAA) ^ AAAA),因为如果满足条件,(x & AAAA) ^ AAAA = 0 ,!((x & AAAA) ^ AAAA) = 1,不满足就为0.
int allOddBits(int x) {
// 4位 1010 = 0xA
int A = 0xA;
// 8位
int AA = A | (A << 4);
// 16位
int AAA = AA | (AA << 8);
// 32位
int AAAA = AAA | (AAA << 16);
return !((x & AAAA) ^ AAAA);
}
5.negate
* negate - return -x * Example: negate(1) = -1. * Legal ops: ! ~ & ^ | + << >> * Max ops: 5 * Rating: 2 */
这个就是~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 */ int isAsciiDigit(int x) { return 2; }
思路:
1、满足条件是在0x30 - 0x39 也就是 11 0000 -- 111001,我们右移六位看看之后的结果是否为0,为0则满足。
2、满足条件是在0x30 - 0x39 也就是 11 0000 -- 111001,所以我们右移四位看看是否满足最后两位是11,也就是右移之后与0b11做异或。
3、因为0x30 - 0x39 我们可以让q = x 和 0xf 与运算,然后看看最后四位是否满足在 0000 - 1001,可以让 res = q - 0xA,如果 res 小于 0 就满足,否则不满足,
可以让cond3 = res >> 31位。!!cond3 为 1就说明满足,为0就说明不满足。
int isAsciiDigit(int x) {undefined
//1、满足条件是 0011 0000 --- 0011 1001
//右移6位看看右移之后的结果是否为0,
int cond1 = !(x >> 6);
//2、因为满足的是11 0000 --- 11 1001
可以右移四位看看最后两位是否是11
int z = x >> 4;
int cond2 = !(z ^ 0b11);
//3、最后四位范围是在 0000 --- 1001 A是正好超过
//可以让x & 0xf,保存最后四位的结果。
int q = x & 0xf;
//然后让q - 0xA 看是否小于0, 直接查看他的符号位
int res = q - 0xA;
int cond3 = !!(res >> 31);
return cond1 & cond2 & cond3;
}
7.conditional
/* * conditional - same as x ? y : z * Example: conditional(2,4,5) = 4 * Legal ops: ! ~ & ^ | + << >> * Max ops: 16 * Rating: 3 */ int conditional(int x, int y, int z) { return 2;
意思就是if(x),x是非0,就返回y,如果是0就返回z。
int conditional(int x, int y, int z) {
//非0数的话c = 1, 0的话 c = 0
int c = !!x;
//如果是非0 c 最后会变成0xf
c = ~c + 1;
//如果满足就返回y,否则返回z
return (y & c) | (~c & z);
//因为如果非0 c = 0xf,那么y & c就还是y,就可以返回y
//如果是0 c = 0x0,那么y & c就是0, 就看z ~c = 1111 就会返回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 */ int isLessOrEqual(int x, int y) { return 2; }
思路:就是让你判断 x - y <= 0 是否成立。
这里面会有四种情况:
- x == y
我们可以让x 和 y做异或 ,因为如果两个相等就会返回0,那我们可以!(x ^ y)就会返回1.
- x + y -
如果x是正的,y是负的,那么x - y > 0 了,就不满足条件。所以我们可以右移31位,记录一下符号位。因为x 是正的,就会等于0, y是负的,就会等于1。定义signX 为x的符号位,signY为y的符号位。所以定义cond2 = !(signY & (!signX))。因为 !signX为1, signY & (!signX) =1,所以!(signY & (!signX)) = 0。所以正好返回0。
- x - y +
和上面一样,x是负的,y是正的。所以signX为1, signY为0。这个是满足条件的,所以返回1,所以定义cond2 = ((!signY) & signX)。因为 !signY为1 ,((!signY) & signX) =1。所以正好返回1。
- x - y - || x + y +
因为正负都一样所以signX为1, signY为1,或者signX为0, signY为0。这个是满足条件的的话,x - y < 0,所以我们定义一个res = (x + (~y) + 1) >> 31,这样我们可以得到他的符号位,如果这个符号位为1,说明满足,如果为0,就是不满足。所以我们res2 = res & 0x1,res2 == 1就是满足,返回1,不满足,返回0。
int isLessOrEqual(int x, int y){
// x - y <= 0
//1、x == y
int cond1 = !(x ^ y);
//2、x + y - 不满足
int signX = x >> 31;// signX = 0
int signY = y >> 31;// signY = 1
int cond2 = !((~signX) & signY);// cond2 = 0
//3、x - y + 满足
//signX = 1, signY = 0
int cond3 = (signX & (~signY));//cond3 = 1
//4、x + y + || x - y -
//当x - y < 0 就说明返回1 否则返回0
//x - y == x + (~y) + 1
int res = (x + (~y) + 1) >> 31;//满足为1, 不满足为0
int res2 = (res & 0x1);//如果为1 说明满足,0为不满足
return cond1 ||(cond2 && (cond3 || res2));
}
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 */ int logicalNeg(int x) { return 2; }
如果x是非0,那说明~x + 1 也不是非0,(x & ((~x) + 1)) >> 31 = 1,如果是0,就会得到0.
int logicalNeg(int x) {
int negX = (~x) + 1;
int sinal = (x & negX) >> 31;//signal = 1说明非0,signal = 0,说明为0
return signal + 1;
}
10.howManyBits
正数 12 = 0000 1100 其中高位1 是第四位,但是还有一个是符号位,所以加上符号位就是50 就默认是1
负数 -13 = 1111 0011, 10011 = -13 这说明我们只需要找到符号位之后第一个0
int howManyBits(int x) {
int iszero = !x;
int flag = x >> 31;
int mask = ((!!x) << 31) >> 31;
x = (flag & (~x)) | ((~flag) & x);
int bit_16, bit_8, bit_4, bit_2, bit_1, bit_0;
//如果你的前 16 位有1, 那么说明至少需要16位,
//有1 (!((!!(x >> 16)) ^ 0x1)) = 0x1
//左移4位正好等于16
bit_16 = (!((!!(x >> 16)) ^ 0x1)) << 4;
x >>= bit_16;
bit_8 = (!((!!(x >> 8)) ^ 0x1)) << 3;
x >>= bit_8;
bit_4 = (!((!!(x >> 4)) ^ 0x1)) << 2;
x >>= bit_4;
bit_2 = (!((!!(x >> 2)) ^ 0x1)) << 1;
x >>= bit_2;
bit_1 = (!((!!(x >> 1)) ^ 0x1));
x >>= bit_1;
bit_0 = x;
int res = bit_16 + bit_8 + bit_4 + bit_2 + bit_1 + bit_0 + 1;
return iszero | (mask & res);
}
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) { }
题目的意思就是让我们算2 * f
首先需要记住浮点数的表示方式
浮点数的表达方式:
v = (-1)^s * M * 2 ^ E
所以我们需要知道这个数的s,expr,frac
1、首先是s 也就是符号为
2、E = expr - bias 单精度biass 127,双精度是1023,所以我们要知道这个expr
因为分成四种情况:规格化、非规格化、无穷大、NaN
2.1规格化:x >> 23位然后 x & 0xff ,得到expr,因为我们是要把x * 2,其实也就是让expr加一就可以,所以对应的就是expr ++;
2.2非规格化:x & 0x7fffff 得到frac,其实就是frac << 1
2.3如果为0,那还是0
2.4 无穷大,那还是无穷大
int floatScale2(unsigned uf){
unsigned s = (uf >> 31) & 0x1;
unsigned expr = (uf >> 23) & 0xff;
unsigned frac = uf & 0x7fffff;
//0
if(expr == 0 && frac == 0){
return uf;
}
//非规格化
if(expr == 0){
//E = 1- 127
frac <<= 1;
return (s << 31) | frac;
}
//无穷大
if(expr == 0xff){
return uf;
}
//规格化
expr ++;
return (s << 31) | (expr << 23) | (frac);
}
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){
unsigned s = (uf >> 31) & (0x1);
unsigned expr = (uf >> 23) & (0xff);
unsigned frac = (uf & 0x7fffff);
if(expr == 0 && frac == 0){
return 0;
}
if(expr == 0xff){
return 1 << 31;
}
if(expr == 0){
return 0;
}
int E = expr - 127;
frac = frac | (1 << 23);
if(E > 31){
return 1 << 31;
}
else if(E < 0){
return 0;
}
if(E >= 23){
frac <<= (E -23);
}
else{
frac >>= (23 - E);
}
if(s)
return ~frac + 1;
return frac;
13.floatPower2
再学学。。。
unsigned f1oatPower2(int x){
if(x < -149){
return 0;
}else if(x < -126){
int shift = 23.+(x+ 126);
return 1 << shift;
}else if(x <= 127){
int expr = x + 127;
return expr << 23;
}else {
return (0xff)<< 23;
}
}