文章目录
1. bitXor(x, y)
/*
* bitXor - x^y using only ~ and &
* Example: bitXor(4, 5) = 1 bitXor(100,101) -> 001
* 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
*/
int tmin(void) {
return 1 << 31;
}
3. isTmax(x)
/*
* isTmax - returns 1 if x is the maximum, two's complement number, 0x7FFFFFFF
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
int isTmax(int x) {
return !(~x + 1 + (~(1 << 31)));
}
4. allOddBits(x)
/*
* 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)
* 如果字中所有奇数位都设置为1,则返回1
* 位从0(最低有效)到31(最高有效)
* Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 2
*/
int allOddBits(int x) {
int a = (0xAA<<24) + (0xAA<<16) + (0xAA<<8) + 0xAA;
return !(~a + 1 + (a & x));
}
5. negate(x)
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) {
return ~x + 1;
}
6. isAsciDigit(x)
/*
* 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) {
int a, b;
a = x + (~(0x30) + 1); // +
b = x + (~(0x3A) + 1); // -
return (!(a >> 31)) & ((b >> 31) & 1);
}
7. conditional
/* conditional - same as x ? y : z
if(x == 0)
{
return z;
}
else return y;
* Example: conditional(2,4,5) = 4
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
int conditional(int x, int y, int z) {
int a[2];
a[0] = z;
a[1] = y;
int sign = !(!x);
return a[sign];
}
8. isLessOrEqual(x, y)
/*
* 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) {
int sx = (x >> 31) & 1, sy = (y >> 31) & 1;
int sign1 = (sx & (!(sy))); // x < 0 & y >= 0
int sign2 = ((sx & sy) & ((((~y + 1 + x) >> 31) & 1) | !((~x + 1 + y) >> 31))); // x < 0 & y < 0
int sign3 = (!(sx | sy)) & (!((~x + 1 + y) >> 31)); // x >= 0 & y >= 0
return sign1 | sign2 | sign3;
}
9. logicalNeg(x)
/*
* logicalNeg - implement the ! operator, using all of
* the legal operators except !
* if x == 0
* return 1;
* else
* return 0;
* Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
int logicalNeg(int x) {
int a[2], index;
a[0] = 1;
a[1] = 0;
index = ((x >> 31) & 1) | ((~x + 1) >> 31);
return a[index];
}
10. howManyBits(x)
/* howManyBits - return the minimum number of bits required to represent x in
* two's complement
* Examples: howManyBits(12) = 5
* howManyBits(298) = 10
* howManyBits(-5) = 4
* howManyBits(0) = 1
* howManyBits(-1) = 1
* howManyBits(0x80000000) = 32
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 90
* Rating: 4
*/
int howManyBits(int x) {
int tmp = (x << 1) ^ x, bit_16, bit_8, bit_4, bit_2, bit_1;
bit_16 = !!(tmp >> 16) << 4;
tmp = tmp >> bit_16;
bit_8 = !!(tmp >> 8) << 3;
tmp = tmp >> bit_8;
bit_4 = !!(tmp >> 4) << 2;
tmp = tmp >> bit_4;
bit_2 = !!(tmp >> 2) << 1;
tmp = tmp >> bit_2;
bit_1 = !!(tmp >> 1);
return 1 + bit_1 + bit_2 + bit_4 + bit_8 + bit_16;
}
11. floatScale2(uf)
/*
* 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) {
unsigned res, sign, exp, frac;
sign = (uf >> 31) & 1;
exp = (uf >> 23) & 0xFF;
frac = uf & 0x7FFFFF;
if (exp != 0 && exp != 0xFF)
{
exp = exp + 1;
}
else if (exp == 0)
{
exp = exp + ((frac << 1) >> 23); //注意进位
frac = (frac << 1) & 0x7FFFFF;
}
else {
return uf;
}
res = (sign << 31) + (exp << 23) + frac;
return res;
}
12. floatFloatInt(uf)
/*
* 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 res, sign, exp, frac;
int bias = (1 << 7) - 1;
sign = (uf >> 31) & 1;
exp = (uf >> 23) & 0xFF;
frac = uf & 0x7FFFFF;
if (exp == 0xFF)
return 0x80000000u;
else if (exp == 0)
{
return 0;
}
else { //提取uf的整数部分
int d = exp - bias - 23;
frac = frac | (1 << 23); // 隐含的1
if (d >= 0)
{
if (d <= 7) //(32 - 1) - 23 - 1
frac = frac << d;
else
return 0x80000000u;
}
else {
d = ~d + 1;
if (d < 24) // 23 + 1
frac = frac >> d;
else
frac = 0;
}
}
res = frac;
return sign ? (~res + 1) : res;
}
13. floatPower2(x)
/*
* 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
*/
unsigned floatPower2(int x) {
int res, exp, frac, bias = (1 << 7) - 1;
if (x < 0) // 如果x小于0
{
if (x < (-22 - bias)) // -23 + 1 - bias(判断是否超出最小能表示的范围)
return 0;
else if (x >= (1 - bias)) // normalized
{
exp = x + bias;
res = exp << 23;
}
else { // denormalized
frac = (23 - (~x + 1 + 1 - bias)) << 1;
res = frac;
}
}
else { // 如果x大于0
if (x > 0xFE - bias) // 判断是否超出最大能表示范围
{
return 0x7F800000;
}
else { // normalized
exp = x + bias;
res = exp << 23;
}
}
return res;
}