Datalab: 人类智慧
unsigned int
和int
部分基本都是人类智慧,而float
则都是最基本的概念,导致这一部分的区分度几乎为0.
bitXor
xor操作的本质实际上是找到\(x\)和\(y\)中不同的位置,那么实际上只需要把\(x\)和~\(y \ \&\)一下,就可以找到x中为\(1\)而\(y\)中为\(0\)的位置,同理可以找到\(x\)中为\(0\)而\(y\)中为\(1\)的位置,再 or 一下就变成了答案,而or可以用~和and 表示。
/*
* 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)) & (~((~y) & x)));
}
tmin
补码可以表示的最小数就是0x80000000,实际上也就是\(1<<31\)
/*
* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmin(void)
{
return (1 << 31);
}
isTmax
只需要判断一个数是不是0x7fffffff,首先我们思考 \(x \ xor\ x+1\) 后的结果,发现还有一个反例,那就是\(-1\),然后单独判断一下\(-1\)即可。
/*
* isTmax - returns 1 if x is the maximum, two's complement number,
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
int isTmax(int x){
return !((!(~x)) | (~(x ^ (x + 1))));
}
allOddBits
我们可以直接构造一个all Odd Bits,且仅有all Odd bits.
然后判断一下结果即可。
/*
* 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
*/
int allOddBits(int x)
{
int cont = 0xaa;
cont = cont | (cont << 8) ;
cont = cont | (cont << 16) ;
return !((~x)&cont);
}
negate
-x = ~x + 1
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x)
{
return (~x) + 1;
}
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
*/
int isAsciiDigit(int x)
{
int pre = x >> 4, lst = x & 0xf, mi3 = ((~3)+1);
int chk = 9 + ((~lst) + 1);
return (!(pre + mi3)) & (!(chk &(1<<31)));
}
conditional
/*
* conditional - same as x ? y : z
* Example: conditional(2,4,5) = 4
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
int conditional(int x, int y, int z)
{
int ans = 0, r = !x, mn = (~1) + 1;
r += mn;
ans += y & r;
r = !x; r = (~r) + 1;
ans += z & r;
return ans;
}
isLessOrEqual
/*
* 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 mi = y + ((~x)+1);
return !(mi & (1<<31));
}
logicalNeg
考虑一个很特殊的情况,如果\(x \ne 0\),\(x\)与\(-x\)总有一个符号位为\(0\),即使\(x = Tmin\)。
那么只需将\(x\ or\ -x\)即可。
/*
* 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 mx = (~x)+1;
return ((x | mx)>>31)+1;
}
howManyBits
人类智慧题,我们将整个过程抽象成一个二分的过程,如果用\(k\)位就可以表示,那么\(x\)一定在\(-2^{k-1}\)~\(2^{k-1}-1\)这个范围之内,然后模拟普通二分的过程即可。
/* 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 flag = 0, ans = 0;
flag = !(!(x >> 16));
flag &= !(!((x >> 16) + 1));
x >>= flag << 4;
ans += flag << 4;
flag = !(!(x >> 8));
flag &= !(!((x >> 8) + 1));
x >>= flag << 3;
ans += flag << 3;
flag = !(!(x >> 4));
flag &= !(!((x >> 4) + 1));
x >>= flag << 2;
ans += flag << 2;
flag = !(!(x>>2));
flag &= !(!((x >> 2) + 1));
x >>= flag << 1;
ans += flag << 1;
flag = !(!(x>>1));
flag &= !(!((x >> 1) + 1));
x >>= flag;
ans += flag;
flag = !(!x); flag &= !(!(x+1));
ans += flag;
return ans + 1;
}
The float parts are achieved very ugly, so please not to blame me.
floatScale2
unsigned floatScale2(unsigned uf)
{
int f = uf & 0x7fffff;
int e = (uf >> 23) & 0xff;
int s = uf >> 31;
if( e == 0xff) return uf;
if (e){
e += 1;
return (s << 31) + (e << 23) + f;
}
if ((f & 0x700000) == 1) e = 1;
f <<= 1;
return (s << 31) + (e << 23) + f;
}
floatFloat2Int
int floatFloat2Int(unsigned uf)
{
int f = uf & 0x7fffff, E;
int e = (uf >> 23) & 0xff;
int s = uf >> 31, Bias = (1<<7) - 1;
int ans = 0;
if (e == 0xff) return 0x80000000u;
if(e)E = e - Bias;
else E = 1 - Bias;
if( E < 0) return 0;
else{
if(E >= 31)return 0x80000000u;
f += (1<<23);
if(E > 23)ans = f<<(E-23);
else ans = f>>(23-E);
}
if (s) return (~ans)+1;
return ans;
}
floatPower2
unsigned floatPower2(int x)
{
if( x < -150) return 0;
if( x >= 129) return 0x7f800000;
if( -126 <= x){
x += 127;
return x << 23;
}
return 1<<(x+150);
}
Next Lab: [[bomblab]]