Data Lab
bitXor
1 2 3 4 5 6 7 8 9 10 11
|
int bitXor(int x, int y) { return (x&~y)|(~x&y); }
|
蛮简单的,直接异或
有无更简便的写法呢?
tmin
关于tmin
我的想法就是
- 对0x00逻辑取反,得到111…111
- 然后右移一位,得到011…111
- 再加1,即可得到100…000这种形式
有个要注意的,就是逻辑取反必须是对无符号数,因此我们首先要写上unsigned
这个地方还不确定,究竟什么时候需要加unsigned
1 2 3 4 5 6 7 8 9 10
|
int tmin(void) { return ( ( ~(unsigned)0x00 ) >> 1 ) + 1;
}
|
isTmax
不能用if之类的控制语句,==这类也不能用,因此需要好好思考思考
我们可以先得出最大的数,其实最大数也知道,就是01111…111这样的,我们用一个mask应该可以
如果和mask进行异或,得到0,说明是相同的,那就取反好了,反之就不是0;如何对于0输出1,对于其他数输出0?
1 2 3 4 5
| int isTmax(int x){ unsigned mask = ~(unsigned)0x00 >> 1; return 1 - (bool)( x ^ mask); }
|
但是,bool类型不能用,这是c…
好吧,忘记了一个重要的事情,那就是——没有bool我可以用!
啊…
那么!
怎么实现呢?(这就是第9题的事情了)
下面是正确代码
1 2 3 4
| int isTmax(int x){ unsigned mask = ~(unsigned)0x00 >> 1; return ! ( x ^ mask); }
|
看了一个讲解,还有一个思路:
目前我们能用的一个确定的数就是0,因此如果需要执行比较判断,我们可以试着从当前数通过一系列操作映射到目标数0
现在就有一个问题,执行操作的时候,可能会同时将其他一些数也映射到0,这个过程大概率不是一一对应的,当然也有可能hhh,可以想一想
总之,对于那些多出来的数,我们需要设计一些方法将它们排除掉
allOddBits
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
int allOddBits(int x) { return !(0xAAAAAAAA ^ (x & 0xAAAAAAAA)); }
int allOddBits(int x){ return !(-1 ^ (x + x >> 1)); }
|
negate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
int negate(int x) { return -x; }
int negate(int x) { return ~x + 1; }
|
isAsciiDigit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
int isAsciiDigit(int x) { int flag_1 = !( (0x30 ^ x) >> 4 ); int a = (0x08 & x) >> 3, b = (0x04 & x) >> 2, c = (0x02 & x) >> 1; int flag_2 = !( (a & b) | (a & c) ); return flag_1 & flag_2; }
|
conditional
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
int conditional(int x, int y, int z) { int mut = ( ( ( ! ! (unsigned)x ) + ~1 + 1 ) ) & (z + ~y + 1); return mut + y; }
|
isLessOrEqual
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
int isLessOrEqual(int x, int y) { return ( ( ( ! ! ((y + ~x + 1) >> 31) ) + ~0) ) & 1; }
int isLessOrEqual(int x, int y) { int xh = ((unsigned)x) >> 31; int yh = ((unsigned)y) >> 31; int flag_pn = !xh & yh; int flag_np = !yh & xh; return (2 + ~flag_pn) & (flag_np | ( ( ( ( ! ! ((y + ~x + 1) >> 31) ) + ~0) ) & 1 ) ); }
|