datalab
   
    
    
    目录
   
- bitXor
- thirdBits
- fitsShort
- isTmax
- fitsBits
- upperBits
- anyOddBit
- byteSwap
- absVal
- divpwr2
- float_neg
- logicalNeg
- bitMask
- isGreater
- logicalShift
- satMul2
- subOK
- trueThreeFourths
- isPower2
- float_i2f
- howManyBits
- float_half
    
    
    bitXor
   
- 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);
    }
    将(x&y)看作矩阵[1,0],[0,0],
    
    (~ x & ~ y)看作矩阵[0,0],[0,1],目标矩阵[0,1],[1,0],因此~ (~ x & ~ y) & ~ (x & y)可以得到目标矩阵
   
    
    
    thirdBits
   
- thirdBits – return word with every third bit (starting from the LSB) set to 1
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 8
- Rating: 1
    int thirdBits(void) {
        int r =0x49;
        r = r|(r<<9);
        r = r|(r<<15);
        return r;
    }
    开始时为1001001,经过第一步后变为18位,此时只需在添加5个1,运用|的特性,
    
    左移15位此时r的第一个1与r<<15的最后一个1重合,得到值
   
    
    
    fitsShort
   
- fitsShort – return 1 if x can be represented as a
- 16-bit, two’s complement integer.
- Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 8
- Rating: 1
    int fitsShort(int x) {
        x = x >> 15;
        x = x ^ (x >> 16);
        return !x;
    }
    分两种:
    
    1.范围之内的正负数——判断17到32位是否一样。
    
    2.在int范围为正short为负的数——还要判断第16位是否等于第32位
   
    
    
    isTmax
   
- 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 r = x+1;
    return !(r+r+!r);
}
利用当x最大时r = x+1 = 0x80000000,r+r = 0,
    
    
    fitsBits
   
- fitsBits – return 1 if x can be represented as an
- n-bit, two’s complement integer.
- 1 <= n <= 32
- Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 15
- Rating: 2
int fitsBits(int x, int n) {
    int a = n + 31;//等于n-1
    int b = x >> 31;
    x = x >> a;
    x = x ^ b;
    return !x;
}
分正数与负数,考虑32位为符号位
- 当x为正数时,右移n-1位后等于0x00000000
- 当x为负数时,右移n-1位后等于0xffffffff
    
    
    upperBits
   
- upperBits – pads n upper bits with 1’s
- You may assume 0 <= n <= 32
- Example: upperBits(4) = 0xF0000000
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 10
- Rating: 1
int upperBits(int n) {
    return ((!!n)<<31)>>(n+(~0));
}
先判断n是否为0,是则!!n = 0;不是则n = 1;在左移至32位,此时0x80000000,在通过32位为1右移后也为1将剩余位数设0
    
    
    anyOddBit
   
- anyOddBit – return 1 if any odd-numbered bit in word set to 1
- Examples anyOddBit(0x5) = 0, anyOddBit(0x7) = 1
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 12
- Rating: 2
int anyOddBit(int x) {
    int a = 0xAA | 0xAA << 8;
    a = a | a << 16;
    return !!(x&a);
}
建立一个32位的偶数位为1的数,偶数位与0&,奇数与1&,如果为0,则没有,反之
    
    
    byteSwap
   
- byteSwap – swaps the nth byte and the mth byte
- Examples: byteSwap(0x12345678, 1, 3) = 0x56341278
- 
byteSwap(0xDEADBEEF, 0, 2) = 0xDEEFBEAD
- You may assume that 0 <= n <= 3, 0 <= m <= 3
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 25
- Rating: 2
int byteSwap(int x, int n, int m) {
    int temp = 0xff;
      n = n << 3;
      m = m << 3;
      int mxorn = ((x >> n) ^ (x >> m)) & temp;//防止出现意外
      x = x ^ ((mxorn << m) | (mxorn << n));
      return x;
}
    
    
    absVal
   
//利用 ^ 运算的半加性,a ^ (a ^ b) = b; b ^ (a ^ b) = a
- absVal – absolute value of x
- Example: absVal(-1) = 1.
- You may assume -TMax <= x <= TMax
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 10
- Rating: 4
int absVal(int x) {
    int val = x>>31;
    return (x^(val))+((val)&1);//x^(val)当x正,取x本身,为负,取x反数。(val)&1 x正取0,x负取1
}
分两种情况:x为正或x为负。x为负时需要取反加1
    
    
    divpwr2
   
- divpwr2 – Compute x/(2^n), for 0 <= n <= 30
- Round toward zero
- Examples: divpwr2(15,1) = 7, divpwr2(-33,4) = -2
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 15
- Rating: 2
int divpwr2(int x, int n) {
    return (x+(x>>31&((1<<n)+~0)))>>n;
}
当x>0,x/(2^n) = x>>n;当x<0,则小数部分大于0时需要x+(1<<n)+~0)之后在进行移位操作
    
    
    float_neg
   
- float_neg – Return bit-level equivalent of expression -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 representations of
- single-precision floating point values.
- When argument is NaN, return argument.
- Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
- Max ops: 10
- Rating: 2
unsigned float_neg(unsigned uf) {
    unsigned ans = uf^0x80000000;
    unsigned nan = uf&0x7fffffff;
    if (nan>0x7f800000)//是否为nan
        return uf;
    return ans;
}
    因为float的正负只与第32位有关不涉及补码,所以用^0x80000000可以完美实现取负操作;
    
    再者排除题目所提及的NAN的情况
   
    
    
    logicalNeg
   
- 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|(~x+1))>>31&1;
}
利用只有0的补码为0,将x与x的补码相或,判断是不是x为0,为0则~ (x|(~x+1))>>31等于1,不为0则等于0
    
    
    bitMask
   
- bitMask – Generate a mask consisting of all 1’s
- lowbit and highbit
- Examples: bitMask(5,3) = 0x38
- Assume 0 <= lowbit <= 31, and 0 <= highbit <= 31
- If lowbit > highbit, then mask should be all 0’s
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 16
- Rating: 3
int bitMask(int highbit, int lowbit) {
  return ((~0)<<lowbit)&((~0)+(2<<highbit));
}
(~ 0)<<lowbit将lowbit位归0,在与(~0)+(2<<highbit)将highbit位归0;剩下及所求
    
    
    isGreater
   
- isGreater – if x > y then return 1, else return 0
- Example: isGreater(4,5) = 0, isGreater(5,4) = 1
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 24
- Rating: 3
int isGreater(int x, int y) {
    int a = (x^y) >> 31;
    int b = x+~(a|y);
    return !(b>>31);
}
- 求x与y的符号是否相同,相同a=0x00000000,不同a=0xffffffff
- 当x与y符号相同时 b=x-y-1 (因为 x==y 时 return 0) 符号不同时 b = x
- 判断b的符号,为1表示 x<=y 为0 表示 x>y
    
    
    logicalShift
   
- logicalShift – shift x to the right by n, using a logical shift
- Can assume that 0 <= n <= 31
- Examples: logicalShift(0x87654321,4) = 0x08765432
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 20
- Rating: 3
int logicalShift(int x, int n) {
    int mask_ = (~0)+(2<<(32+~n));//32+~n是为了防止溢出
    return (x>>n)&mask_;
}
//只需同时考虑x<0的情况;将[31-n+1,31]位变为0,在&x>>n
    
    
    satMul2
   
- satMul2 – multiplies by 2, saturating to Tmin or Tmax if overflow
- Examples:
- 
satMul2(0x30000000) = 0x60000000
- 
satMul2(0x40000000) = 0x7FFFFFFF (saturate to TMax)
- 
satMul2(0x60000000) = 0x80000000 (saturate to TMin)
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 20
- Rating: 3
int satMul2(int x) {
    int a=x<<1;//*2操作
    int b=x>>31;//符号位
    int c=(x^a)>>31;//判断是否超过Tmax或Tmin,为0xffffffff表示超了
    int tmin=1<<31;
    return ((~c)&a)+(c&(~b+tmin));//(~c)&a在超过int表示时进行"归0"操作,
    //c&(~b+tmin)中c用来判断是否需要表示为Tmax或Tmin;当x为正时~b+tmin表示tmin-1
}
    对x进行<<1实现x
    
     2操作;由于超过int表示范围x的符号位会与x
    
    2不同,以此判断返回值
   
    
    
    subOK
   
- subOK – Determine if can compute x-y without overflow
- Example:
- 
subOK(0x80000000,0x80000000) = 1,
- 
subOK(0x80000000,0x70000000) = 0,
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 20
- Rating: 3
int subOK(int x, int y) {
    int a = x + (~y + 1);
    int b = x ^ y;
    int c = a ^ x;
    return !((b & c) >> 31);
}
判断要同时满足两个条件,x与y符号不同,x与x-y符号不同的时候返回0
    
    
    trueThreeFourths
   
- trueThreeFourths – multiplies by 3/4 rounding toward 0,
- avoiding errors due to overflow
- Examples: trueThreeFourths(11) = 8
- 
trueThreeFourths(-9) = -6
- 
trueThreeFourths(1073741824) = 805306368 (no overflow)
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 20
- Rating: 4
int trueThreeFourths(int x)
{
    int y=x&0x3;//判断/4后的1,2位 0.75 0.5 0.25
    x=x>>2;
    return (x<<1)+((y+y+y+((x>>31)&0x3))>>2)+x;
}
    思路为1/4
    
     x + 1/2
    
    x + 四舍五入
    
    判断是否为4的倍数,若不是当
   
- 小于4时,
- x为正数且大于4,四舍五入;
- x为负数,8需要四舍五入
    
    
    isPower2
   
- isPower2 – returns 1 if x is a power of 2, and 0 otherwise
- Examples: isPower2(5) = 0, isPower2(8) = 1, isPower2(0) = 0
- Note that no negative number is a power of 2.
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 20
- Rating: 4
int isPower2(int x) {
  return ((!(x&(x+~0))) & ((~(x>>31)&(!!x))));
}
利用当x = 2^n,则x-1的[0,n-1]位都为1;判断是否为正和x-1的0到n-1位(未知)是否全等于1
    
    
    float_i2f
   
- float_i2f – Return bit-level equivalent of expression (float) x
- Result is returned as unsigned int, but
- it is to be interpreted as the bit-level representation of a
- single-precision floating point values.
- Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
- Max ops: 30
- Rating: 4
unsigned float_i2f(int x) {
    int s,h,exp,f,flag;
    unsigned temp,result;
    if(!x)
    return x;             //由于规范数情况不包含0,所以先处理0情况。
    s=(x>>31)&0x01;
    if(s)
    x=~x+1;              //获得符号位,并将x变为正值。
    h=0;
    temp=x;
    while(!(temp&0x80000000))
    {
     temp<<=1;
     h++;
    }                    //获得x的最高有效位,即确定fraction的位数。
    temp=temp<<1;
    exp=127+31-h;  //根据单精度浮点数规则计算出exp,和fraction位数。
    f=31-h;
    flag=0;               //进行向偶舍入
    if((temp&0x1ff)>0x100)
    flag=1;              //出现在规定位置后大于0b100的情况就进1.
    if((temp&0x3ff)==0x300)
    flag=1;              //出现最后一位为1,且下一位为1的情况也进1(向偶取整)
    result=(s<<31)+(exp<<23)+(temp>>9)+flag;//计算最终结果
    return result;
}
确认是否能正常转为float,排除不规范,0,和无穷的情况,操作如上图
    
    
    howManyBits
   
- 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 temp = x ^ (x << 1);//将负数转为正数相同的判别,同时加一个符号位(只能用32位才能表示的数不用加)
    int bit_16,bit_8,bit_4,bit_2,bit_1;
    bit_16 = !!(temp >> 16) << 4;//判断长度是否大于16
    temp = temp >> bit_16;、//对折操作
    bit_8 = !!(temp >> 8) << 3;//同上
    temp = temp >> bit_8;
    bit_4 = !!(temp >> 4) << 2;
    temp = temp >> bit_4;
    bit_2 = !!(temp >> 2) << 1;
    temp = temp >> bit_2;
    bit_1 = !!(temp >> 1);
    return 1 + bit_1 + bit_2 + bit_4 + bit_8 + bit_16;
}
    对折法,分4次对折,每次的长度可以对折就将x对折一半,直到折成 1bit 为止,最后用 1(bit) 加上折掉的长度
    
    因为符号位始终都要站一个格子,所以不是只能用32位表示的都要加1位
   
    
    
    float_half
   
- float_half – Return bit-level equivalent of expression 0.5*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 float_half(unsigned uf) {
    unsigned s=uf&0x80000000;//取符号位
    unsigned exp=uf&0x7f800000;//取31到23位
    int lsb=((uf&3)==3);//31,32两位是否都为1,用于补位
    if (exp==0x7f800000)//无穷
        return uf;
    if (exp<=0x800000)//*0.5后不规范
        return s|(((uf^s)+lsb)>>1);
    if (exp)//正常
        return (uf-0x800000);
}
判断能否正常除以2;无穷,*0.5后不规范单独操作
 
