rating 1
int bitAnd(int x, int y) {
return ~((~x)|(~y));
}
~(A&B)=(~A)|(~B).
int evenBits(void) {
int x = 0x55, y = (x << 8) | x;
return (y << 16) | y;
}
0x55=01010101,将x复制4倍合在一起.
int fitsShort(int x) {
int y = (x << 16) >> 16;
return !(x ^ y);
}
x 左移16位再右移16位,相当于把x转为16进制数.
int isTmax(int x) {
int y = ~x;
return (!(y + y)) & (!(!y));
}
x为最大值=>(~x)+(~x)=0
特殊情况:x=-1 => ~x=0
int minusOne(void) {
return ~0;
}
~0=-1.
int upperBits(int n) {
int mi = ~0;
return ((!n) + mi) & ((~(2 << (n + mi))) << (33 + (~n)));
}
0<n<32: (~(1 << n)) << (32 - n), 1左移n位取反得到前n位为1的数,左移32-n位得到答案;
n=0: !n + ~0 = 0,故答案为0;
n=32: 将 1 << n 变为 2 << (n - 1) 防止错误.
rating 2
int allEvenBits(int x) {
int a = 0x55;
int b = (a << 8) | a;
int c = (b << 16) | b;
return !((x & c) ^ c);
}
和evenbits类似,制造一个偶数位均为1的数与其取并后看是否相等.
int byteSwap(int x, int n, int m) {
int n4 = n << 3, m4 = m << 3;
int nb = (x >> n4) & 0xFF;
int mb = (x >> m4) & 0xFF;
int rest = x ^ (nb << n4) ^ (mb << m4);
return (nb << m4) | (mb << n4) | rest;
}
先把第n字节和第m字节取下来,再获得把原数第n字节和第m字节抹掉的数,再把它们反向取或。
int copyLSB(int x) {
return x << 31 >> 31;
}
只留下符号位。
int divpwr2(int x, int n) {
return (x + (((1 << n) + (~0)) & (x >> 31))) >> n;
}
难点在于向0取整,当x为负数时将x加上(1<<n)-1,这样能保证向上取整。
int leastBitPos(int x) {
return ((~x) + 1) & x;
}
即lowbit,检验可知。
int oddBits(void) {
int x = 0xAA << 8 | 0xAA;
return x << 16 | x;
}
与evenbits类似。
rating 3
int bitMask(int highbit, int lowbit) {
int t = (2 << highbit) + (~(1 << lowbit)) + 1;
int x = highbit + (~lowbit) + 1;
return (~(x >> 31)) & t;
}
答案=(1<<(highbit +1)) - (1<< lowbit)
若highbit - lowbit < 0 则输出0,用一个&额外判断.
int isLess(int x, int y) {
int x0 = (x >> 31), y0 = (y >> 31);
int rest = ((x + (~y) + 1) >> 31) & 1;
int o = x0 ^ y0;
return (o & (y0 + 1)) + (~o & rest);
}
难点在于不能直接做减法(负数减正数=正数),要额外判断一下x,y的符号
y0 + 1为x,y异号的答案,x,y同号时直接相减判断符号即可.
int logicalShift(int x, int n) {
return (x >> n) + (((x >> 31) & !!n) << (33 + (~n)));
}
x为负数时右移补0,把补的1加上1<<(32-n)全部进位即可.
int satMul2(int x) {
int x0 = x >> 31;
int mulx = x << 1;
int x1 = mulx >> 31;
int x2 = x0 ^ x1, x3 = ~x2;
int Tmin = 1 << 31, Tmax = Tmin + ~0;
return (x3 & mulx) + (x2 & x0 & Tmin) + (x2 & x1 & Tmax);
}
分类讨论x和x<<1的符号,每种情况若满足条件则返回对应值,否则返回0,然后把所有情况相加。
int subOK(int x, int y) {
int x0 = x >> 31, y0 = y >> 31;
int z0 = (x + (~y) + 1) >> 31;
return !((x0 ^ y0) & (!(y0 ^ z0)));
}
判断x,y符号同x-y符号,x,y同号=》可以减,x,y异号=》判断y与x-y是否异号...
rating 4
int bang(int x) {
int a = x | (x >> 16);
int b = (a | (a >> 8)) & 0xFF;
return (((~b) + 1) >> 31) + 1;
}
判断x是否某一位为1:将后16位与前16位取或,前8位与后8位取或,...,则可知道是否含1.
上述函数使用了一种优化:或到前8位后直接判断符号(0或正数)
int bitParity(int x) {
int a = x ^ (x >> 16);
int b = a ^ (a >> 8);
int c = b ^ (b >> 4);
int d = c ^ (c >> 2);
return (d ^ (d >> 1)) & 1;
}
与上题类似,后16位与前16位取异或,...,只需确认第1位的奇偶性即可。
int isPower2(int x) {
return !(((x & ((~x) + 1)) ^ x) | (x >> 31) | !x);
}
用lowbit得到x为1最低位的数,直接判断x是否等于它,注意x为负数/0特判.
unsigned float_i2f(int x) {
int bias = 127;
int t = 0;
int s, y, t0, exp, M, bs, qs, qM, o = 0;
if(x == (1 << 31))
{
s = 1;
exp = 31 + bias;
return (s << 31) | (exp << 23);
}
if(x < 0) x = -x, s = 1;else s = 0;
if(!x) return 0;
y = x;
while(y) t += 1, y >>= 1;
t0 = t - 1;
exp = t0 + bias;
if(t0 <= 23) M = (x - (1 << t0)) << (23 - t0);
else
{
bs = 1 << (t0 - 24);
qs = (bs << 1) - 1;
qM = x & qs;
M = (x - (1 << t0)) >> (t0 - 23);
if(qM != bs) o = qM > bs;
else o = M & 1;
}
return ((s << 31) | (exp << 23) | M) + o;
}
如果x是负数先转正数;再分步提取exp、M.
int leftBitCount(int x) {
int pos = ~0;
pos = pos + (((x + (1 << (pos + 16))) >> 31) & 16);
pos = pos + (((x + (1 << (pos + 8))) >> 31) & 8);
pos = pos + (((x + (1 << (pos + 4))) >> 31) & 4);
pos = pos + (((x + (1 << (pos + 2))) >> 31) & 2);
pos = pos + (((x + (1 << (pos + 1))) >> 31) & 1);
return (x >> 31) & (32 + ~pos);
}
倍增,初始pos为0,判断pos+16,pos+8,...,pos+1之后的位是否均为1,是就加上16,8,...,1,否则不加。




Comments | NOTHING