写在前面,以前没有接触过限定运算符的问题。所以出现了限定运算符,并且大多数逻辑运算都不可以使用,一些控制流语句都不可以使用,还是不太适应的。做了几天,还有三道做不下去了。
1.bitXor,思路:同时为0或者1的时候才为0,其他情况为1,所以可以先&操作(x & y),获得同时为1的。再将x,y进行~,然后再&,得到就是同时为0的(~x ^ ~y)。然后在这两个式子中都为0的就是01或10的。所以可以将这两个式子|运算再~就可以了。
/*
* bitXor - x^y using only ~ and &
* Example: bitXor(4, 5) = 1
* Legal ops: ~ &
* Max ops: 14
* Rating: 1
*/
int bitXor(int x, int y) {
int result = ~(x & y) & ~(~x & ~y);
return result;
}
2.tmin
直接1 << 31
/*
* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmin(void) {
return 1<<31;
}
3.isTmax
观察发现Tmax * 2 + 2 == 0,测试函数时,发现-1和Tmax行为一致,所以需要去掉-1的影响,-1加上1就变成0了再!就变成1,所以可以这样做来去掉-1的影响。
//2
/*
* 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) {
int y = x + 1;
return !((y + y) | !y); //括号中的表达式只有当x==Tmax时才会为0
}
4.allOddBits,我开始的思路是用^来x进行0xaaaaaaaa比较。所以有式子!(x ^ (x | 0xaaaaaaaa)),基于以下事实。
1. | 运算可以忽略掉偶数位的影响。比如需要n ,m 需要第一位是否相同,就可以|0xfffffffe,这样就可以保持其他位相同了。
2. 假如x的所有奇数位的都为1,x | 0xaaaaaaaa必然不会影响x位模式。
/*
* 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 n1 = 0xaa;
n1 = (n1 << 8) | n1;
n1 = (n1 << 16) | n1;
//int n2 = n1 | 0xaa;
//int n3 = (n2 << 16) | n2;
return !(x ^ (x | n1)); //n1就是0xaaaaaaaa
}
5.negate
取反加一就行。
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) {
return ~x + 1;
}
6.isAsciiDigit
在0x30-0x39的范围的数,他们减去0x30符号位为0,减去0x3为1。所以比较符号位满足这个条件就可以得到结果1。现在需要考虑溢出。溢出后会不会导致相同的结果。发现不用。
//3
/*
* 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) {
return !((x + ~0x30 + 1) >> 31) & !!((x + ~0x3a + 1) >> 31);
//return (!((x+~48+1)>>31))&!!((x+~58+1)>>31);
}
7.conditional
因为需要出y,或z,所以式子里面需要构造出的是可以选择的。矛盾的两个式子。不能同时为0。第一个式子,所以当x不为0时,将它变为1,再进行取反加1,可以得到0xffffffff,当x为0时,通过上述运算必定是为0。
第二个式子,当x为0,0变成-1,,1的位模式就是0xffffffff,那么就可以有了。当x不为0,其他式子都变成0;
/*
* 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) {
return ((~!!x + 1) & y) | ((!!x + ~0x1 + 1) & z);
}
8.isLessOrEqual
x-y >= 0, 那么可以得到符号位为0(同为正数同为负数)。
当不同符号位,只要x是<=0,就可以输出1。
这题思路参考博客
https://blog.csdn.net/tzh476/article/details/51284938#commentBox
/*
* 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 result = ((x >> 31) ^ (y >> 31));
return (!result & !!((x + ~y + 1) >> 31)) | !(x ^ y) | (!!result & !((!!(x >> 31)) ^ 0x1));
}
9.islogicNeg
思路:找出0和其他非零值的不同。然后找不到哪里的不同
https://blog.csdn.net/tzh476/article/details/51284938#commentBox
这个博客给了我思考的切入点。
0的负数还是0,符号位相同,00,其他数的负数是相反数也就是符号位不同10,01。然后测试时需要测试Tmin,测试函数时都需要将Tmin做为测试的例子。
测试Tmin时,发现Tmin的相反数还是Tmin,符号位相同。,11,所以需要把Tmin给筛出来。
//4
/*
* 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) {
return (((~x + 1) | x) >> 31 & 0x1) ^ 0x1;
}
10.floatScale2
这道题的大多数思路还是由
https://blog.csdn.net/tzh476/article/details/51284938#commentBox
给出。感谢。这个需要很强大的观察能力了,才能得到这个。
/float
/*
* 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
*/
unsigned floatScale2(unsigned uf) {
unsigned frac = uf & 0x007fffff;
unsigned exp = uf & 0x7f800000;
unsigned sign = uf &(1 << 31);
if(!(exp ^ 0x7f800000)) {e
return uf;
}
if(!(exp ^ 0x0)) {
if(frac & 0x00400000) {
// exp = (((exp >> 23) + 0x1) << 23) & 0x7f800000;
exp += 0x00800000;
frac <<= 1;
}
else {
frac <<= 1;
}
}
else {
//exp = (((exp >> 23) + 0x1) << 23) & 0x7f800000;
exp += 0x00800000;
if(exp == 0xff) {
frac = frac & 0x0;
}
}
return (sign | exp | frac);
}
还有howmanybits, floatFloat2Int,floatPower2三道题没有做。。可能以后才回来做了。