/*
* minusOne - return a value of -1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 2
* Rating: 1
*/
int minusOne(void) {
return ~0;
}
/*
* fitsShort - return 1 if x can be represented as a
* 16-bit, two's complement integer.
* Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 8
* Rating: 1
*/
int fitsShort(int x) {
int y = x >> 15;
return !( (y >> 16) ^ y);
}
/*
* bitNor - ~(x|y) using only ~ and &
* Example: bitNor(0x6, 0x5) = 0xFFFFFFF8
* Legal ops: ~ &
* Max ops: 8
* Rating: 1
*/
int bitNor(int x, int y) {
return ~x & ~y;
}
/*
* allOddBits - return 1 if all odd-numbered bits in word set to 1
* Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 2
*/
int allOddBits(int x) {
int mask = 0xAA | 0xAA << 8;
mask = mask | mask << 16;
x = x & mask;
return !(mask^x);
}
/*
* divpwr2 - Compute x/(2^n), for 0 <= n <= 30
* Round toward zero
* Examples: divpwr2(15,1) = 7, divpwr2(-33,4) = -2
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 2
*/
int divpwr2(int x, int n) {
//全0或者全1
int signx = x >> 31; //
int mask = (1 << n) + (~0);//得到2^n - 1
int bias = signx & mask;//如果x是正数,则bias为0,即不用加,直接移位
//如果x为负数,加上偏置量之后在移位
return (x + bias) >> n;
}
/*
* sign - return 1 if positive, 0 if zero, and -1 if negative
* Examples: sign(130) = 1
* sign(-23) = -1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 10
* Rating: 2
*/
int sign(int x) {
return (x >> 0x1F) | !!x;
}
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) {
return (~x) + 1; // 取反加1
}
/*
* addOK - Determine if can compute x+y without overflow
* Example: addOK(0x80000000,0x80000000) = 0,
* addOK(0x80000000,0x70000000) = 1,
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 3
*/
int addOK(int x, int y) {
int mark1 = (x ^ y) >> 31;
int mark2 = ~((x + y) ^ y) >> 31;
return !!(mark1 | mark2);
}
/*
* ezThreeFourths - multiplies by 3/4 rounding toward 0,
* Should exactly duplicate effect of C expression (x*3/4),
* including overflow behavior.
* Examples: ezThreeFourths(11) = 8
* ezThreeFourths(-9) = -6
* ezThreeFourths(1073741824) = -268435456 (overflow)
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 3
*/
int ezThreeFourths(int x) {
x = x + (x << 1);
return (x+(x>>31&3))>>2;}
/*
* isGreater - if x > y then return 1, else return 0
* Example: isGreater(4,5) = 0, isGreater(5,4) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
int isGreater(int x, int y) {
int s=(y+~x+1)>>31;
int sx=x>>31;
int sy=y>>31;
return (s&1)^(!(s^sx)&(s^sy));
}
/*
* rempwr2 - Compute x%(2^n), for 0 <= n <= 30
* Negative arguments should yield negative remainders
* Examples: rempwr2(15,2) = 3, rempwr2(-35,3) = -3
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 3
*/
int rempwr2(int x, int n) {
return x + (~((x + ((x >> 31)&((1 << n) + (~0)))) >> n << n)) + 1;
}
/*
* rotateRight - Rotate x to the right by n
* Can assume that 0 <= n <= 31
* Examples: rotateRight(0x87654321,4) = 0x76543218
* Legal ops: ~ & ^ | + << >> !
* Max ops: 25
* Rating: 3
*/
int rotateRight(int x, int n) {
int mask = (~0) + (1<<n);
int offset = 32 + ~n + 1;
int r = (x&mask)<<offset;
return ((x>>n)&(~(mask<<offset)))|r;
}
/*
* greatestBitPos - return a mask that marks the position of the
* most significant 1 bit. If x == 0, return 0
* Example: greatestBitPos(96) = 0x40
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 70
* Rating: 4
*/
int greatestBitPos(int x) {
int n = 0;
n += ((!!(x&((~0)<<(n+16)))) << 4);
n += ((!!(x&((~0)<<(n+8)))) << 3);
n += ((!!(x&((~0)<<(n+4)))) << 2);
n += ((!!(x&((~0)<<(n+2)))) << 1);
n += (!!(x&((~0)<<(n+1))));
return (1<<n)&x;
}
/*
* bang - Compute !x without using !
* Examples: bang(3) = 0, bang(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
int bang(int x) {
return ~(x|(~x+1))>>31&1;
}
/*
* 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
*/
int float_f2i(unsigned uf) {
int sign=uf>>31;
int exp=(uf>>23)&0xff;
int frac=uf&0x007fffff;
int right=157-exp;
int abs;
if (exp<0x7f)
return 0;
if (exp>157)
return 0x80000000;
abs=(0x40000000+(frac<<7))>>right;
if (sign)
return -abs;
else
return abs;
}
/*
* float_twice - 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 float_twice(unsigned uf) {
unsigned f = uf;
if ((f & 0x7F800000) == 0) //
{
//左移一位
f = ((f & 0x007FFFFF) << 1) | (0x80000000 & f);
}
else if ((f & 0x7F800000) != 0x7F800000)
{
f =f + 0x00800000;
}
return f;
}