/* * bitXor - x^y using only ~ and & * Example: bitXor(4, 5) = 1 * Legal ops: ~ & * Max ops: 14 * Rating: 1 */ intbitXor(int x, int y) { int a = (~x) & y; int b = x & (~y); int c = (~a) & (~b); return ~c; }
/* * isTmax - returns 1 if x is the maximum, two's complement number, * and 0 otherwise * Legal ops: ! ~ & ^ | + * Max ops: 10 * Rating: 1 */ intisTmax(int x) { int c = (x+1) ^ (~x); int d = !(~x); return !(c | d); }
allOddBits
构造奇数位为1,偶数位为0的mask,再看x&mask^mask是否为0
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/* * 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 */ intallOddBits(int x) { int m = 0xAA; m = (m << 8) | m; m = (m << 16) | m; return !((x & m) ^ m); }
isAsciiDigit
$$x <= 0x39 –> x & (~0x3f) == 0$$
$$0x30 <= x <= 0x39 –> x & 0x30 ^ 0x30 == 0$$
$$x & 0xf < 9 –> if x & 8 != 0 then x & 6 == 0$$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/* * 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 */ intisAsciiDigit(int x) { int m = 0x3f; // int n = ~m; int y = x & (~0x3f); // the higher bits in x should be 0 y |= (x & 0x30) ^ 0x30; // 0x30 <= x <= 0x3f --> m = 0 //y !=0 --> false m = (x >>3) & 1 & (!!(x & 6)); return !(m|y); }
conditional
构造两个mask,根据x的true or false将mask1,mask2分别设置为0xffff,0x0,再分别与上y,z即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/* * conditional - same as x ? y : z * Example: conditional(2,4,5) = 4 * Legal ops: ! ~ & ^ | + << >> * Max ops: 16 * Rating: 3 */ intconditional(int x, int y, int z) { int m = !x; int n; m = (m << 1) | m; m = (m << 2) | m; m = (m << 4) | m; m = (m << 8) | m; m = (m << 16) | m; n = ~m; return (m & z) | (y & n); }
/* * isLessOrEqual - if x <= y then return 1, else return 0 * Example: isLessOrEqual(4,5) = 1. * Legal ops: ! ~ & ^ | + << >> * Max ops: 24 * Rating: 3 */ intisLessOrEqual(int x, int y) { int z = 1 & ((y + 1 + (~x)) >> 31);// y - x x = (x >> 31) & 1; y = (y >> 31) & 1; int k = 1 & ((y + 1 + (~x)) >> 31);// k = 1 if x < 0 and y >= 0, return 1 int m = 1 & ((x + 1 + (~y)) >> 31);// m = 1 if x >= 0 and y < 0, return 0 return ((!z) | k) & (!m); }
logicalNeg
只有当x为0时,x与-x的符号位都为0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/* * 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 */ intlogicalNeg(int x) { int y = (x >> 31) & 1; // x < 0 --> y = 1, x >=0 --> y = 0 int z = ~x + 1; z = (z >> 31) & 1; // x >0 --> z = 1 return1 ^ (y | z); }
/* * 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 */ intfloatFloat2Int(unsigned uf) { unsigned frac = uf & 0x7fffff; intexp = (uf >> 23) & 0xff; unsigned s = uf & (1 << 31); int E = exp - (1 << 7) + 1; if(!frac && !exp || E <0) { return0; } if(exp == 0xff || E > 30) { return0x80000000u; } frac |= 1 << 23; frac >>= (23 - E); if(s) { frac = ~frac + 1; } return frac; }
/* * 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 */ unsignedfloatPower2(int x) { // return 2; int bias = (1 << 7) - 1; intexp = x + bias; if(x < -23 - bias) { return0; } if(x >= 0xff - bias) { return0xff << 23; } if(x < -bias) { int n = -x - bias; return1 << (23 - n); } returnexp << 23; }