//1
/*
* 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) & ~(x & y);
}
/*
* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmin(void) {
return 0x1<<31;
}
//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) {
//returns 1 if x == 0x7fff ffff
int y = x + 1; // y == 0x8000 0000, y + y == 0
//but y != 0
return !(y + y) & !!y;
}
/*
* 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 y = 0xaa;
//printf("%x\n",y);
y = y + (y<<8);
//printf("%x\n",y);
y = y + (y<<16);
//printf("%x\n",y);
//y = 0xaaaaaa
return !((x & y) ^ y);
}
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) {
//x=0x00000002 == 2
//y=0xfffffffe == -2
return ~x + 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) {
//0x30 == 0011 0000
//0x39 == 0011 1001
//x - 0x39 - 1 < 0 && 0x30 - x - 1 < 0
//printf("\n前项= %x\n",(x+~0x39)>>31);
//printf("后项= %x\n",(0x30+~x)>>31);
return !!(((x+~0x39)>>31) & ((0x30+~x)>>31));
}
/*
* 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) {
// ~!x = 0xffffffff(x == 1) or 0x00000000(x == 0)
x = (~!!x) + 1;
return (x & y) | (~x & z);
}
/*
* 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 xs = x>>31, ys = y>>31;//0xffffffff or 0x00000000
// x<0,y>0 y-x>=0 not x>0,y<0
return (xs & !ys) | (!((y + ~x + 1)>>31) & !((!xs) & ys));
//Hooooooooooraaaaaaaay!!!!
}
//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) {
//logicalNeg(0) = 1, logicalNeg(others) = 0
//compare sign before and after neg
return ((x>>31) | ((~x + 1)>>31)) + 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) {
//printf("\n\nthis time, x = %x\n", x);
int b16, b8, b4, b2 ,b1;
//the sign of x, equals 1 if x >= 0
int xs = !(x>>31);
//the next two lines imply
//x = xs? x : (~x)
int temp = (~!!xs) + 1;
x = (temp & x) | (~temp & (~x));
xs = 1;
//if x == 0 then make xs == 0
xs = xs & !!x;
//printf("x=%x, %d\n", x, x);
b16 = !!(x>>16);
temp = ~b16 + 1;//b16==0,temp=0;b16==1,temp=0xffffffff
x = (~temp & x) | (temp & (x>>16));//if b16==1 then x=x>>16
//printf("x=%x, %d\n", x, x);
b8 = !!(x>>8);
temp = ~b8 + 1;
x = (~temp & x) | (temp & (x>>8));
//printf("x=%x, %d\n", x, x);
b4 = !!(x>>4);
temp = ~b4 + 1;
x = (~temp & x) | (temp & (x>>4));
//printf("x=%x, %d\n", x, x);
b2 = !!(x>>2);
temp = ~b2 + 1;
x = (~temp & x) | (temp & (x>>2));
//printf("x=%x, %d\n", x, x);
b1 = !!(x>>1);
//printf("x=%x, %d\n", x, x);
//int a = (b16<<4) + (b8<<3) + (b4<<2) + (b2<<1) + b1;
//printf("a = %d\n%d%d%d%d%d%d\n", a,b16,b8,b4,b2,b1,xs);
return (b16<<4) + (b8<<3) + (b4<<2) + (b2<<1) + b1 + 1 + xs;
}
//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) {
//start implementation
//float: 1s 8exp 23frac, exp=E+Bias, Bias=127
//(-1)^s * frac * 2^E
//int s = uf>>31;//0xffffffff(neg) or 0(pos)
//这题抄的
unsigned sign = uf & 0x80000000u;
unsigned exp = uf & 0x7f800000;
unsigned frac = uf & 0x007fffff;
//INF and NaN
if(exp == 0x7f800000) {
return uf;
}
//denormalized nums and 0
if(!exp) {
return sign | uf<<1;
}
exp += 1<<23;
//add to +INF
if(exp == 0x7f800000) {
frac = 0;
}
return sign | exp | frac;
// printf("\n\nuf = %x\n", uf);
// int frac = uf<<8;
// printf("frac = %x\n", frac);
// frac = frac>>8;//0(sign) 00000000(exp) frac or 1 11111111 frac
// printf("frac = %x\n", frac);
// int exp = uf>>23;//0 exp or 1 exp
// if(exp>>8) { //clear sign bit
// exp += 0xffffff00;//now exp = 0 exp
// }
// printf("exp = %x\n", exp);
// //to make frac = 0 00000000 frac
// if(frac>>23 && exp) { //exp!=0
// frac += (1<<23);
// printf("if(frac>>23) frac = %x\n", frac);
// }
// //if exp!=0 then exp+=1
// if(exp) {
// frac += (1<<23);
// printf("if(exp) frac = %x\n", frac);
// }
}
/*
* floatFloat2Int - Return bit-level equivalent of expression (int) f
* for floating point argument f.
* Argument is passed as unsigned int, but
* it is to be interpreted as the bit-level representation of a
* single-precision floating point value.
* Anything out of range (including NaN and infinity) should return
* 0x80000000u.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
int floatFloat2Int(unsigned uf) {
//这题基本是抄的
//float: 1s 8exp 23frac, exp=E+Bias(normalized)
//E=1-bias(denormalized, exp=0), Bias=127
//(-1)^s * frac * 2^E
//NaN:exp=0xff,frac!=0;infinity:exp=0xff,frac==0
unsigned sign = uf>>31;
unsigned exp = uf & 0x7f800000;
unsigned frac = (uf & 0x007fffff) + 0x00800000;
int res;
//printf("\nexp = %x\n", exp);
int E = (exp>>23) - 127;
//printf("E = %x, %d\n", E,E);
if(E < 0) {
return 0;
}
if(E > 31) {
return 0x80000000u;
}
if(E < 23) {
res = frac>>(23 - E);
} else {
res = frac<<(E - 23);
}
return sign ? (~res + 1) : res;
}
/*
* floatPower2 - Return bit-level equivalent of the expression 2.0^x
* (2.0 raised to the power x) for any 32-bit integer x.
*
* The unsigned value that is returned should have the identical bit
* representation as the single-precision floating-point number 2.0^x.
* If the result is too small to be represented as a denorm, return
* 0. If too large, return +INF.
*
* Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatPower2(int x) {
//min denorm:0 00000000 00...1 = 2^(1-127-23), E=-149
if(x<-149) return 0;
//max denorm:0 00000000 10...0 = 2^(1-127-1), E=-127
if(x<=-127) return 1<<(x+149);
//max norm:0 11111110 00...0 = 2^(2^8-2-127), E=127
if(x<=127) return (x+127)<<23;
//if(x>127)
return 0xff<<23;
}