注意,本文代码出于节省括号避免繁杂的考虑,对运算符优先级利用得比较充分,比如 1>>n+1 等价于 1>>(n+1),所以代码里写了1>>n+1。
/*
* bitAnd - x&y using only ~ and |
* Example: bitAnd(6, 5) = 4
* Legal ops: ~ |
* Max ops: 8
* Rating: 1
*/
int bitAnd(int x, int y) {
return ~(~x|~y);
}
/*
* getByte - Extract byte n from word x
* Bytes numbered from 0 (LSB) to 3 (MSB)
* Examples: getByte(0x12345678,1) = 0x56
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 6
* Rating: 2
*/
int getByte(int x, int n) {
int bias = n<<3;
return (x>>bias)&0xFF;
}
/*
* logicalShift - shift x to the right by n, using a logical shift
i
* Can assume that 0 <= n <= 31
* Examples: logicalShift(0x87654321,4) = 0x08765432
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 3
*/
int logicalShift(int x, int n) {
return (1<<32+~n<<1)+~0 & (x>>n);
//equal to ((1<<31-n<<1)-1)&(x>>n);
//负号优先级高于移位
}
因为不能用-
,所以用取反加一代替取负
构造低32-n
bit的1来提取移位后的数值
因为移位量不能小于0或大于等于32,所以对于n可能是0而导致移位量是32的情况,先移位31位,再移位1位
小技巧,如果n移位k,k ∈ [0, 32],则可以
n>>(k-!!k)>>!!k
/*
* bitCount - returns count of number of 1's in word
* Examples: bitCount(5) = 2, bitCount(7) = 3
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 40
* Rating: 4
*/
int bitCount(int x) {
int mark1 = 0x55;
int mark2 = 0x33;
int mark3 = 0x0F;
mark1 |= mark1<<8;
mark1 |= mark1<<16;
mark2 |= mark2<<8;
mark2 |= mark2<<16;
mark3 |= mark3<<8;
mark3 |= mark3<<16;
x = (x>>1&mark1)+(x&mark1); //every two bits; clear record;
x = (x>>2&mark2)+(x&mark2); //every four bits; clear record;
x = (x>>4&mark3)+(x&mark3); //every eight bits; clear record;
x = (x>>8)+x; //every 16 bits; record in the low 8 bits;
x = (x>>16)+x; //every 32 bits; record in the low 8 bits;
return x&0xFF;
}
/*
* bang - Compute !x without using !
* Examples: bang(3) = 0, bang(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
int bang(int x) {
x |= x>>1;
x |= x>>2;
x |= x>>4;
x |= x>>8;
x |= x>>16;
return ~x&0x1;
}
/*
* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmin(void) {
return 1<<31;
}
/*
* 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
*/
int fitsBits(int x, int n) {
return !(x>>n+~0)|!((x>>n+~0)+1);
//equal to !(x>>n-1) | !((x>>n-1)+1)
}
/*
* 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) {
int t = x>>31;
return (x+(t&1<1)+1))>>n;
//equal to (x+(t&1<>n;
//note that & 的优先级低于<<
}
x<0 ? x+(pow(2,n)-1)>>n : x>>n
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) {
return ~x+1;
}
/*
* isPositive - return 1 if x > 0, return 0 otherwise
* Example: isPositive(-1) = 0.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 8
* Rating: 3
*/
int isPositive(int x) {
return ~(x>>31)&!!x;
}
/*
* 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 !!(x>>31&~(y>>31)) | !(~(x>>31)&(y>>31))&(x+~y+1>>31) | !(x^y);
//equal to !!(x>>31&~(y>>31)) | !(~(x>>31)&(y>>31))&(x-y>>31) | !(x^y)
}
x<0&&y>0 | !(x>0&&y<0)&&(x-y>0) | x==y
/*
* ilog2 - return floor(log base 2 of x), where x > 0
* Example: ilog2(16) = 4
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 90
* Rating: 4
*/
int ilog2(int x) {
int mark1 = 0x55;
int mark2 = 0x33;
int mark3 = 0x0F;
mark1 |= mark1<<8;
mark1 |= mark1<<16;
mark2 |= mark2<<8;
mark2 |= mark2<<16;
mark3 |= mark3<<8;
mark3 |= mark3<<16;
x |= x>>1;
x |= x>>2;
x |= x>>4;
x |= x>>8;
x |= x>>16;
x >>= 1;
x = (x>>1&mark1)+(x&mark1); //every two bits; clear record;
x = (x>>2&mark2)+(x&mark2); //every four bits; clear record;
x = (x>>4&mark3)+(x&mark3); //every eight bits; clear record;
x = (x>>8)+x; //every 16 bits; record in the low 8 bits;
x = (x>>16)+x; //every 32 bits; record in the low 8 bits;
return x&0xFF;
}
/*
* float_neg - Return bit-level equivalent of expression -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
*/
unsigned float_neg(unsigned uf) {
unsigned t = uf&0x7FFFFFFF;
if(t^0x7F800000 && (t>>23)+1>>8)
return uf;
else
return uf^0x80000000;
}
(t>>23)+1>>8
判断exp是否全1/*
* float_i2f - Return bit-level equivalent of expression (float) x
* Result is returned as unsigned int, but
* it is to be interpreted as the bit-level representation of a
* single-precision floating point values.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
unsigned float_i2f(int x) {
unsigned shiftLeft=0;
unsigned afterShift, tmp, flag;
unsigned absX=x;
unsigned sign=0;
//special case
if (x==0) return 0;
//if x < 0, sign = 1000...,abs_x = -x
if (x<0)
{
sign=0x80000000;
absX=-x;
}
afterShift=absX;
//count shift_left and after_shift
while (1)
{
tmp=afterShift;
afterShift<<=1;
shiftLeft++;
if (tmp & 0x80000000) break;
}
if ((afterShift & 0x01ff)>0x0100)
flag=1;
else if ((afterShift & 0x03ff)==0x0300)
flag=1;
else
flag=0;
return sign + (afterShift>>9) + ((159-shiftLeft)<<23) + flag;
}
//from http://www.cnblogs.com/tenlee/p/4951639.html
分情况处理0、负数、正数
要处理舍人
- 向接近的舍入
- 如果处于中间,向偶数舍入
舍入时,如果尾数加一,exp有可能需要进位,这时候直接加一效果一样,可以导致exp进位,不需要特殊处理。如果exp等于0xFE,那么进位就变成了inf,也是合法的
/*
* 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 t = uf&0x7FFFFFFF;
unsigned temp = t&0x7F800000;
unsigned temp2 = uf&0xFF800000;
int expFull = !(temp^0x7F800000);
if(t^0x7F800000 && expFull)
return uf;
if(expFull){
return temp2;
}
if(!(t&0x7F800000)){
unsigned k = (uf&0x7FFFFF);
return temp2+(k<<1);
}
return (temp>>23)+1<<23 | uf&0x807FFFFF;
}