1. bitXor
- bitXor - x^y using only ~ and &
- Example: bitXor(4, 5) = 1
- 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
- isTmax - returns 1 if x is the maximum, two’s complement number,
- and 0 otherwise
- Legal ops: ! ~ & ^ | +
- Max ops: 10
- Rating: 1
解题思路:Tmax = ~(Tmax+1), 排除同样满足此条件的0xffffffff
int isTmax(int x) {
return !(x ^ (~(x + 1))) & !!(~x);
}
同理, Tmin = ~Tim + 1, 排除同样满足此条件的0x0
int isTmin(int x) {
return !(x ^ (~x + 1)) & !!(x);
}
4. allOddBits
- 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
解题思路:
- x & 0xAAAAAAAA = 0xAAAAAAAA。
- 构造0xAAAAAAAA
int allOddBits(int x) {
int a = 0xAA | 0xAA << 8;
a = a | 0xAA << 16;
a = a | 0xAA << 24;
return !((a&x)^a);
}
5. negate
- negate - return -x
- Example: negate(1) = -1.
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 5
- Rating: 2
解题思路:
-x = x的补码,补码=反码+1
int negate(int x) {
return (~x+1);
}
6. isAsciiDigit
- 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
解题思路:
依据两个原理:
- 计算机的减运算等于加补码,补码=反码+1
- 对于32位int来说,若一个数>=0,右移31位为0;若为负数,右移31位为1。
int isAsciiDigit(int x) {
int left = x + (~(0x30)+1);
int right = (~x+1) + 0x39;
return !(left >> 31) & !(right >> 31);
}
7. conditional
- conditional - same as x ? y : z
- Example: conditional(2,4,5) = 4
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 16
- Rating: 3
解题思路:
- 当x只取0x00000000或0xFFFFFFFF时,结果为(x & y) | (~x & z)。
- 只需要排除当x != 0时,x = 0xFFFFFFFF。
int conditional(int x, int y, int z) {
x = (!!x) << 31 >> 31;
return ((x & y) | (~x & z));
}
8. isLessOrEqual
- isLessOrEqual - if x <= y then return 1, else return 0
- Example: isLessOrEqual(4,5) = 1.
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 24
- Rating: 3
解题思路:
- 理论上y-x >= 0即可。
- 但是如果x, y正负不同,相减可能会溢出。
- 所以分两种情况讨论,如果两个数符号相等,判断相减;如果两个数符号不同,判断符号。
int isLessOrEqual(int x, int y) {
int a = !((x >> 31) ^ (y >> 31));
return (a & !((y + (~x + 1)) >> 31)) | (~a & !(y >> 31));
}
9. logicalNeg
- 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
解题思路:
0和-0的最高位为0,将正数转化为负数,那么只有0的最高位为0
int logicalNeg(int x) {
return ~((x | (~x + 1)) >> 31) & 0x1;
}
10. howManyBits
- 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
解题思路:
- 补码的最高表示位前面的所有数字应该都是全0(正数)或是全1(负数)。
- 将原数与左移一位后的数字异或则最高的不同的那个位置为1,我们只需要找到这个最高的不同位即可。
int howManyBits(int x) {
int temp = x ^ (x << 1);
int bit_16,bit_8,bit_4,bit_2,bit_1;
bit_16 = !!(temp >> 16) << 4;
temp = temp >> bit_16;
bit_8 = !!(temp >> 8) << 3;
temp = temp >> bit_8;
bit_4 = !!(temp >> 4) << 2;
temp = temp >> bit_4;
bit_2 = !!(temp >> 2) << 1;
temp = temp >> bit_2;
bit_1 = !!(temp >> 1);
return 1 + bit_1 + bit_2 + bit_4 + bit_8 + bit_16;
}
11. floatScale2
- 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
解题思路:
- IEEE浮点数格式一共分为三种形式,弱规范数,NAN以及一般的数。
- NAN直接返回
- 弱规范数直接左移1位但要保留符号位。
- 一般数的话尾数不变,只移动指数位并保持符号位不变。
unsigned floatScale2(unsigned uf) {
unsigned a = (uf >> 23) & 0xff;
unsigned flag = uf >> 31 << 31;
int temp = uf;
if (a == 0xff)
return uf;
else if (a == 0)
{
temp = uf << 1;
//temp = temp & (~(0xff << 23));
temp = temp | flag;
}
else
{
temp = temp + (0x1<<23);
temp = temp | flag;
}
return temp;;
}
12. floatFloat2Int
- 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
解题思路:
- 此题的解题关键在于分几种情况,先将符号位拿出单独讨论,当指数位-127>=32位时,溢出,返回0x80000000u,当指数位-127 < 0时,是小于1的小数,返回0即可。
- 剩下的情况一种是指数位-127>=23位时,将尾数位左移多出的位;当<23时,尾数位右移缺失的位。
- 再将最后的结果根据符号位的判断加上正负。
int floatFloat2Int(unsigned uf) {
int a = ((uf >> 23) & 0xff) - 127;
int flag = uf >> 31;
if (a >= 32)
return 0x80000000u;
else if (a < 0)
return 0;
else
{
int temp = (uf | 0x800000) & 0xffffff;
if (a >= 23)
{
int e = a - 23;
temp = temp << e;
}
else
{
int e = 23 - a;
temp = temp >> e;
}
return flag ? -temp : temp;
}
}
13. floatPower2
- 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) {
if (x > 127)
{
return 0x7f800000;
}
else if (x < -127)
{
return 0x0;
}
else
{
return (x + 127) << 23;
}
}