/*
* bang - Compute !x without using !
* Examples: bang(3) = 0, bang(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
int bang(int x) {
int tmp = x | (~x+1);
tmp = (tmp >> 31) + 1;
return tmp;
}
/*
* 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
*/
int logicalNeg(int x) {
int tmp = x | (~x+1);
tmp = (tmp >> 31) + 1;
return tmp;
}
bang or logicalNeg
思路:只有0的补码位或本身首位为0
/*
* 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 mask,s;
mask = 0x11 | (0x11 << 8);
mask = mask | (mask << 16);
s = x&mask;
s = s + ((x>>1)&mask);
s = s + ((x>>2)&mask);
s = s + ((x>>3)&mask);
s = s + (s>>16);
mask = 0xF | (0xF << 8);
s = (s&mask) + ((s>>4)&mask);
return (s + (s>>8)) & 0x3F;
}
bitCount
思路:
先构建0x11111111,再分别将x右移三次获得每个byte里1的个数(不大于4)
将前半段计数与后半段相加,此时后四个byte里存储两个byte中1的个数(不大于8)
以此类推,再进行两次合并即可得到所有的bit数
/*
* copyLSB - set all bits of result to least significant bit of x
* Example: copyLSB(5) = 0xFFFFFFFF, copyLSB(6) = 0x00000000
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int copyLSB(int x) {
x = x << 31;
x = x >> 31;
return x;
}
countingLSB
思路:简单,不解释
/*
* evenBits - return word with all even-numbered bits set to 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 8
* Rating: 2
*/
int evenBits(void) {
int n = 0x55;
n = (n<<8) | n;
n = (n<<16) | n;
return n;
}
evenBits
思路:构建一个mask,复制两次即可(参考bitCount)
/*
* 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) {
int t = x;
int minus = 32 + (~n+1);
x = x<<minus;
x = x>>minus;
return !(t^x);
}
fitsBits
思路:若可以用n-bits表示那么左移32-n位再右移32-n后和原来相同
/*
* 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 m = n<<3;
int mask = 0xff << m;
x = (mask & x) >> m;
x = x&0xff;
return x;
}
getByte
简单不解释
/*
* 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 x1 = (x >> 31) & 1;
int y1 = (y >> 31) & 1;
int xy = !!(x^y);
int minus = !((x + (~y+1)) >> 31);
int ans = ((x1^y1)&y1) | (xy & minus & (!(x1^y1)));
return ans;
}
isGreater
思路:
考虑是否一正一负,若x正y负则返回1;(x1^y1)&y1
考虑是否相等,相等则返回0;!!(x^y)
/*
* isNonNegative - return 1 if x >= 0, return 0 otherwise
* Example: isNonNegative(-1) = 0. isNonNegative(0) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 6
* Rating: 3
*/
int isNonNegative(int x) {
int ans = !(x>>31);
return ans;
}
isNonNegative
/*
* isNotEqual - return 0 if x == y, and 1 otherwise
* Examples: isNotEqual(5,5) = 0, isNotEqual(4,5) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 6
* Rating: 2
*/
int isNotEqual(int x, int y) {
return !!(x^y);
}
isNotEqual
/*
* 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: 4
*/
int leastBitPos(int x) {
int m = ~x + 1;
int n = m & x;
return n;
}
leastBitPos
思路:考虑leastBitPos之前都是0,取反加一后leastBitPos位为1,亦或原数字后只有该位为1,则为答案
/*
* logicalShift - shift x to the right by n, using a logical shift
* Can assume that 1 <= n <= 31
* Examples: logicalShift(0x87654321,4) = 0x08765432
* Legal ops: ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
int logicalShift(int x, int n) {
int new_x, mask;
new_x = x >> n;
mask = 0x1 << 31 >> (n+(~0));
mask = ~mask;
return new_x & mask;
}
logicalShift
思路:用带0的mask覆盖即可
/*
* satAdd - adds two numbers but when positive overflow occurs, returns
* maximum possible value, and when negative overflow occurs,
* it returns minimum positive value.
* Examples: satAdd(0x40000000,0x40000000) = 0x7fffffff
* satAdd(0x80000000,0xffffffff) = 0x80000000
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 30
* Rating: 4
*/
int satAdd(int x, int y) {
int add,over,pover,nover,ans;
add = x+y;
over = (add^x)&(add^y);
pover = ((over&~x)>>31)&1;
nover = ((over&x)>>31)&1;
ans = ((~(1<<31))&(~pover+1))+((1<<31)&(~nover+1))+((~(!(pover|nover))+1)&add);
return ans;
}
satAdd
思路:
溢出只有两种情况,xy都正 x+y为负,xy都负 x+y为正,over变量可以监控是否溢出
结合over和x的正负可以判断是positive_over 还是 negative_over
答案讨论三种情况:pover则返回Tmax,nover则返回Tmin,都不溢出则返回计算值
/* 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 mask,cal,tmp,dig = 16,minus = ~0,add;
tmp = x;
x = ((x>>31) ^ x) + !!(x>>31);
mask = ~((1<<dig)+minus);
cal = !!(x&mask);
cal = ((cal << 1) + minus) << 3;
dig = dig+cal;
mask = ~((1<<dig)+minus);
cal = !!(x&mask);
cal = ((cal << 1) + minus) << 2;
dig = dig+cal;
mask = ~((1<<dig)+ minus);
cal = !!(x&mask);
cal = ((cal << 1) + minus) << 1;
dig = dig+cal;
mask = ~((1<<dig)+minus);
cal = !!(x&mask);
cal = ((cal << 1) + minus);
dig = dig + cal;
mask = ~((1<<dig) + minus);
cal = !!(x&mask);
dig = dig + cal;
mask = ((1<<(dig+minus))+minus);
add = !!(x&mask);
return (add&(tmp>>31)) + dig + !(tmp>>31) + (~(!tmp)) + 1;
}
howManyBits
思路:
先统一变为正数计算
构建mask = 0xffff0000,若mask&x为0则继续考虑0xffffff00,若为1则考虑0xff000000
以此类推,直到确定位数,在此基础上+1(符号位)
接下来考虑是否为负数且最高位的后一位是否为1,若是,则位数+1
/*
* 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 x1 = (x >> 31) & 1;
int y1 = (y >> 31) & 1;
int xy = !!(x^y);
int minus = !((x + (~y+1)) >> 31);
int ans = ((x1^y1)&y1) | (xy & minus & (!(x1^y1)));
return !ans;
}
isLessOrEqual
思路:isGreater结果取反(见上)