/* * minusOne - return a value of -1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 2 * Rating: 1 */ intminusOne(void) { return ~0; }
implication
蕴涵算子, iff前真后假时返回0,列出真值表猜表达式。
1 2 3 4 5 6 7 8 9 10 11 12
/* * implication - return x -> y in propositional logic - 0 for false, 1 * for true * Example: implication(1,1) = 1 * implication(1,0) = 0 * Legal ops: ! ~ ^ | * Max ops: 5 * Rating: 2 */ intimplication(int x, int y) { return (!x)|y; }
leastBitPos(x)
找到非零的最低位。
1 2 3 4 5 6 7 8 9 10 11
/* * leastBitPos - return a mask that marks the position of the * least significant 1 bit. If x == 0, return 0 * Example: leastBitPos(96) = 0x20 * Legal ops: ! ~ & ^ | + << >> * Max ops: 6 * Rating: 2 */ intleastBitPos(int x) { return ((x+(~0))^x)&x; }
rotateLeft(x,n)
把x向高位方向旋转n位。
1 2 3 4 5 6 7 8 9 10 11
/* * rotateLeft - Rotate x to the left by n * Can assume that 0 <= n <= 31 * Examples: rotateLeft(0x87654321,4) = 0x76543218 * Legal ops: ~ & ^ | + << >> ! * Max ops: 25 * Rating: 3 */ introtateLeft(int x, int n) { return (x<<n) | (~((~0) << n) & (x>>(32+1+(~n)))); }
conditional(x,y,z)
返回x ? y : z,考虑!运算可以得到0或者1,左移31位再算数右移回来就可以把每一位都变成相同,这相当于是一个有选择的mask,可以用来做选择。
1 2 3 4 5 6 7 8 9 10
/* * 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) { return (~(((!x)<<31)>>31) & y) | ((((!x)<<31)>>31) & z); }
/* * oneMoreThan - return 1 if y is one more than x, and 0 otherwise * Examples oneMoreThan(0, 1) = 1, oneMoreThan(-1, 1) = 0 * Legal ops: ~ & ! ^ | + << >> * Max ops: 15 * Rating: 2 */ intoneMoreThan(int x, int y) { return !((x+1) ^ y) & !(!(y ^ (1 << 31))); }
fitsBits(x,n)
比较x最后n位的32位扩展的值是不是和x一样即可。
1 2 3 4 5 6 7 8 9 10 11 12
/* * fitsBits - return 1 if x can be represented as an * n-bit, two's complement integer. * 1 <= n <= 32 * Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 15 * Rating: 2 */ intfitsBits(int x, int n) { return !((x << (32 + ~n + 1) >> (32 + ~n + 1)) ^ x); }
multFiveEighths(x)
*5就是左移2位再加上自身,然后处理向0舍入的细节。
1 2 3 4 5 6 7 8
intmultFiveEighths(int x) { int y = (x << 2) + x; int z = y >> 3; int round = !!(0x07 & y); int mask = (y >> 31) & 0x1; int ans = z + (mask & round); return ans; }
satMul2(x)
判断左移之后有没有变符号来判断溢出。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/* * satMul2 - multiplies by 2, saturating to Tmin or Tmax if overflow * Examples: satMul2(0x30000000) = 0x60000000 * satMul2(0x40000000) = 0x7FFFFFFF (saturate to TMax) * satMul2(0x60000000) = 0x80000000 (saturate to TMin) * Legal ops: ! ~ & ^ | + << >> * Max ops: 20 * Rating: 3 */ intsatMul2(int x) { int y = x << 1; int Tmin = 1 << 31; int mask = ((Tmin) & (y ^ x)) >> 31; int ans1 = y & (~mask); int ans2 = mask & (~(((Tmin) & x) >> 31) ^ ((Tmin))); return ans1 + ans2; }
/* * ilog2 - return floor(log base 2 of x), where x > 0 * Example: ilog2(16) = 4 * Legal ops: ! ~ & ^ | + << >> * Max ops: 90 * Rating: 4 */ intilog2(int x) { int a,b,c,d,e; a = !(!(x>>16)) << 4; x = x >> a; b = !(!(x>>8)) << 3; x = x >> b; c = !(!(x >> 4)) << 2; x = x >> c; d = !(!(x >> 2)) << 1; x = x >> d; e = !(!(x >> 1)); return a + b + c + d + e; }
Floating-Point Operations
这部分内容有关浮点数运算,熟悉浮点数表示就不太难,也没什么好说明的直接上码吧。。。。。。
float_abs(x)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/* * float_abs - Return bit-level equivalent of absolute value of 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 representations of * single-precision floating point values. * When argument is NaN, return argument.. * Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while * Max ops: 10 * Rating: 2 */ unsignedfloat_abs(unsigned uf) { int ans = uf & 0x7FFFFFFF; if(ans > 0x7F800000) //NaN return uf; return ans; }
/* * float_f2i - 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 */ intfloat_f2i(unsigned uf) { int x,y,ans1; x=(uf>>23)&0xFF; y=(uf & 0x007FFFFF)|(1 << 23); if(x>157) return0x80000000u; if(x<127) return0; if(x > 150) ans1 = y<<(x-150); else ans1 = y>>(150-x); if(((uf>>31)&0x1)==1) return ~ans1 + 1; else return ans1; }
/* * float_negpwr2 - 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 */ unsignedfloat_negpwr2(int x) { unsigned INF = 0xFF << 23; // 阶码全1 if (x > 149) return0; if (x < ~(0x7F)+1) return INF; if(x <= 149 && x > 126) return1<<(149+~x+1); if(x <= 126 && x >= ~(0x7F)+1) return (~x+1+127)<<23; return2; }