DataLab

在这里插入图片描述

/* 
 * bitXor - x^y using only ~ and & 
 *   Example: bitXor(4, 5) = 1
 *   Legal ops: ~ &
 *   Max ops: 14
 *   Rating: 1
 */
int bitXor(int x, int y) {
   // De-Morgan's Law
   // x XOR y = (~x)y+x(~y)
   int r1=~(~x&y);
   int r2=~(x&~y);
   return ~(r1&r2);
   //return ~(~x&~y) & ~(x&y);
}
/* 
 * tmin - return minimum two's complement integer 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 4
 *   Rating: 1
 */
int tmin(void) {
    // 0x80000000 is -2^31
    // 0x7fffffff is 2^31-1
    return 1<<31;
}
/*
 * 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) {
   // Max+1=Min
   // !(~11111111)=1, else !(~xxxxxxxx)=0
   // If x is max, then x^(x+1) is 00000000---use !convert to 11111111
   // use !(x+1) to exclude -1(11111111)
   return !(!(x+1)+~(x^(x+1)));
}
/* 
 * 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) {
// 1010 1010 to check odd bits
// m=1010 1010 1010 1010 1010 1010 1010 1010
   int m=0xAA; 
   m=m<<8 |m;    
   m=m<<8 |m;
   m=m<<8 |m;
   return !(m ^(m & x));
}
/* 
 * negate - return -x 
 *   Example: negate(1) = -1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 5
 *   Rating: 2
 */
int negate(int x) {
  return ~x+1;
}
/* 
 * 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 a=(x>>4) ^ 0x3;  // 0x3? should be the same, return 0 if valid
    int b=(x>>3) & 0x1;  // return 1 if 8's place is 1, return 0 is always valid  
    int c=!(x & 0x6);    //return 1 if 2's and 4's place all 0 (valid)
    // a has to be the same and if b is 1 then c has to be 0
    return (!a & !(b & !c));
}
/* 
 * 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=!!x; // if x=0, set x=0; else set x=1
    x=~x+1; // if x=0 ,set x=0; else set x=0xffffffff
    return (x & y)|(~x & z); // use x ~x | as alternative for condition.If x=0,then return z; if x=0xffffffff, return y 
}
/* 
 * 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) {
    // We want y-x>=0 return 1; y-x<0 return 0
    // When x and y in different sign, y-x might overflow
    // Xsign      Ysign
    //   0          0    ?
    //   0          1    (y<x)   False
    //   1          0    (y>=x)  True
    //   1          1    ? 
    int Xsign=x>>31&0x1; //return 1 if x<0  return 0 if x>0
    int Ysign=y>>31&0x1; //return 1 if y<0  return 0 if y>0
    int diff=((y+(~x+1))>>31)&0x1; //return 0 if y-x>=0 (valid)
    int right=(!(Ysign)& Xsign); // return 1 if diff is dimissed
    int wrong=(!(Xsign)& Ysign); // rethrn 0 if diff is needed
    return right | (!wrong & !diff);
}
/* 
 * 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) {
    // 0 ----> 0+1=1
    // Not 0 -----> -1(0xffffffff)+1=0
    // Make sign bit 1 and shift arithmatic left to get 0xffffffff
    return (( x | (~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
 */
NOTE:
1.Sign extension for higher bits:
  a.if x > 0, say 13 in 4 bits representation is 1101; 
    In 8 bits is 0000 1101; Higher bits use 0 to extend
  b.if x < 0, say -5 in normally 32 bits representation is 1111111111111111111111111111011           
  But in 4 bits representation is 1011(1(sign bits)+011(value bits)); 
  Higher bits use 1 to extend
2. Binary search in bits manipulation:
  +--------------+--------+-----+---+--+
  32             16       8     4   2  1 
  +--------------+--------+-----+---+--+
  a. First shift x>>16, check high 16 bits:
     if x>>16 all zero, then b16=0, check low bits(1~16), x do not need to shift right(IF SHIFT RIGHT WE WILL LOSE OUR ANSWER)
     if x>>16 has 1, then result should be in 16~32 bit, set base b16=16, x needs to get shifted right: x=x>>16(lOCATE OUR ANSWER) 
  
int howManyBits(int x) {
    // One could add from 0-->32 all the time 
    // I choose to use binary search
    // First check the hign 16 bits, then the low 8 bits....
    // Last check the last remaining bit
    // If x > 0, we want to know the first appearance of 1; if x       // <0, we need the first appearance of 0. After flipping the       // negative number x = (sign & ~x) | (~sign & x), we only need     // to find the first appearance of 1.
  int sign = x >> 31;  
  x = (sign & ~x) | (~sign & x);  // If x is negative number, flip it
  int b16 = !!(x >> 16) << 4;  // whether most significant 16 bits have 1. If yes, b16 =16, if not, b16 = 0
  x = x >> b16;  // If yes, right shift 16 bits; if no, do not right shift.
  int b8 = !!(x >> 8) << 3;  // whether the rest most significant 8 bits have 1.
  x = x >> b8;
  int b4 = !!(x >> 4) << 2;
  x = x >> b4;
  int b2 = !!(x >> 2) << 1;
  x = x >> b2;
  int b1 = !!(x >> 1);
  x = x >> b1;
  int b0 = x;
  return b16 + b8 + b4 + b2 + b1 + b0 + 1;  // 1 is the sign bit.
}
/* 
 * 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) {
    int exp=(uf>>23) & 0xff;
    int sign= uf & (1<<31);
    int frac= uf & 0x7fffff;
    if(exp==0xff) return uf; // NaN or Infinity
    if(exp==0x0){
    // For demoralized number:
    // We have (-1)^s * 0.x0x1....x22 * 2^(-126)
    // If x0=0, then 2*f should be:
    // (-1)^s * 0.x1x2....x[22]0 * 2^(-126)
    // == signbit 00000000 x1x2.....x[22]0
    //If x0=1, then 2*f should be:
    // (-1)^s * 1.x1x2....x[22]0 * 2^(-126)
    // == signbit 00000001 x1x2.....x[22]0
    // Shift left would get the result
       return (uf<<1) | sign;
    }
    // To get 2*f, we have to increase exp by 1
    exp=exp+1;
    // Check whether 2*f is Infinity representation 
    if(exp==0xff){
       return sign | 0x7f800000;
    }
    else{
    // No overflow, add them together
       return sign | (exp<<23) | 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) {
  int exp = (uf >> 23) & 0xFF;
  int frac = uf & 0x7FFFFF;
  int sign = uf & (1 << 31); 
  if (exp == 0xFF) return 0x80000000u;  // Out of range, return 0x8000000
  if (exp == 0x0) return 0;  // Denormed number, means its range is (-1, 1) just return 0
  int frac1 = frac | 0x800000;  // Add the hidden 1 in front of frac
  int ActualExp = exp - 127; 
  if (ActualExp > 31) return 0x80000000; // Max of int is 2^32-1, 2^32 is out of int's bound
  else if (ActualExp < 0) return 0; 
  // If ActualExp is 23 then do not need to shift
  // Consider ActualExp in (23,31] and 23 and [0,23)
  if (ActualExp > 23) frac1 <<= (ActualExp - 23);
  else frac1 >>= (23 - ActualExp);
  if (sign) return ~frac1 + 1;  // if negative number
  else return frac1;
}
/* 
 * 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) {
    int exp=x+127;
    // Result is positive, sign bit is always 0
    // Denorm number
    if(exp<=0) return 0;
    // exp > 1111 1110(254) Infinity
    if(exp>=255) return 0x7f800000;
    return exp<<23;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值