第一题
/* 
 * bitXor - x^y using only ~ and & 
 *   Example: bitXor(4, 5) = 1
 *   Legal ops: ~ &
 *   Max ops: 14
 *   Rating: 1
 */
允许使用的二元运算符只有&,
 观察x & y的结果发现(此处只观察每一个单一bit):
 x & y = 1 (11)
 x & y = 0(01,10,00)
记 ck1= x & y,只要对ck1取反,再排除00就可以了,
 想到:
 x & y = 1 (11)
 则有:
 ~x & ~y = 1 (00)
 再记,ck2=~x & ~y
所以答案有两个要求,一是 x & y == 0,二是 ~x & ~y != 1
 即 ans= ~ck1 & ~ck2;
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
 */
Tmin就是符号位为1,其他所有位为0。
 那么 就是:
int tmin(void) {
  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
 */
Tmax有一个挺独特的点: Tmax + 1 == ~Tmax;
 不过 -1 也会满足这一等式,但只有这两个数会满足此等式,这就是一个不错的出发点。
 总体思路:
- 不妨先检查 x+1 是否等于 ~x
- 再保证x不等于-1
记 ck1 = !( (x+1) ^ (~x) )
 a ^ b 当且仅当 a == b 时,为 0;
 再做一次逻辑取反,以确保 x+1 == ~x
下一步就是确保 x != -1
 即 x+1 != 0
 记 ck2 = !!(x+1)
所以ans = ck1 & ck2;
当时写得有点没条理,但意思是一样的。
int isTmax(int x) {
  int ck1=~x;
  int ck2=x+1;
  int ret=!(ck1^ck2);
  // Then check if x==-1 0r x+1==0
  return !!ck2 & ret;
}
第四题
/* 
 * 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
 */
记得: 1010101 0 b i n a r y = 17 0 d e c = 0 x A A 10101010_{binary}=170_{dec}=0xAA 10101010binary=170dec=0xAA
主要思路:
- 可以用0xAAAAAAAA与x做 按位& 来获取它的所有偶数位,记 cpt = 0xAAAAAAAA & x
- 在对比ck1 与 0xAAAAAAAA是否相等。
int allOddBits(int x) {
  int t= 170 + (170<<8) + (170<<16) + (170<<24);
  return !((t & x)^(t));
}
第五题
/* 
 * negate - return -x 
 *   Example: negate(1) = -1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 5
 *   Rating: 2
 */
用原书中的加法逆元来解释这个所谓的“-x”,在int中不是每一个数加个负号就可以变成自己的加法逆元的,比如Tmin就会溢出,但好消息是,每个数都能用方程: x + x a d v e r s e = 0 x+x_{adverse}=0 x+xadverse=0 来解出一个加法逆元。
我们发现:~x + x = 0xFFFFFFFF,即 -1
 那 ~x+x+1 = -1+1 =0
 所以x的加法逆元为~x+1
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(x+(1<<31)+1) & (x+(1<<31)+1)
 *   Rating: 3
 */
其实就是让我们判断一个数是否在 [0x30,0x39] 中。
 在位运算中,判断一个数小于零是最简单的操作,所以需要对数字作出一点等价变换:
 
    
     
      
       
        x
       
       
        ≥
       
       
        0
       
       
        x
       
       
        30
       
       
       
        等价于
       
       
       
        !
       
       
        (
       
       
        x
       
       
        −
       
       
        0
       
       
        x
       
       
        30
       
       
        <
       
       
        0
       
       
        )
       
      
      
       x\ge 0x30 \quad \textbf{等价于}\quad !(x-0x30< 0)
      
     
    x≥0x30等价于!(x−0x30<0)
同样地,也有:
 
    
     
      
       
        x
       
       
        ≤
       
       
        0
       
       
        x
       
       
        39
       
       
       
        等价于
       
       
       
        !
       
       
        (
       
       
        0
       
       
        x
       
       
        39
       
       
        −
       
       
        x
       
       
        <
       
       
        0
       
       
        )
       
      
      
       x\le 0x39 \quad \textbf{等价于}\quad !(0x39-x< 0)
      
     
    x≤0x39等价于!(0x39−x<0)
int isAsciiDigit(int x) {
 int left= !((x+~(0x30)+1)>>31);
 int right=!((0x39+(~x)+1)>>31);
 return left & right;
}
第七题
/* 
 * conditional - same as x ? y : z 
 *   Example: conditional(2,4,5) = 4
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 16
 *   Rating: 3
 */
初次做这道题会有点无从下手,但掌握以下思想会变简单不少:
 return (entry1 & y) | (entry2 & z):
 其中当 x != 0 时,entry1=0xFFFFFFFF,而 entry2=0x0;
 当 x == 0 时,entry1=0x0,而 entry2=0xFFFFFFFF;
 那么:
 
     
      
       
        
         e
        
        
         n
        
        
         t
        
        
         r
        
        
         
          y
         
         
          1
         
        
        
         =
        
        
         (
        
        
         (
        
        
         !
        
        
         !
        
        
         x
        
        
         )
        
        
         <
        
        
         <
        
        
         31
        
        
         )
        
        
         >
        
        
         >
        
        
         31
        
       
       
         entry_{1}=((!!x)<<31)>>31 
       
      
     entry1=((!!x)<<31)>>31
 那entry2就等于 ~entry1
int conditional(int x, int y, int z) {
  int bm_y= ((!!x)<<31)>>31;
  int bm_z= ~bm_y;
  return (bm_y & y) | (bm_z & z);
}
第八题
/* 
 * isLessOrEqual - if x <= y  then return 1, else return 0 
 *   Example: isLessOrEqual(4,5) = 1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 24
 *   Rating: 3
 */
这题挺恶心的,看上去挺容易但会很容易错。
 以下,把int分为两类:自然数,和负数。
 主要思路:
- 符号比较,数的类型不同一定有天然的大小关系
- 比较同号的数:
 a. 同为自然数可以正常比较,因为对正数取负是没有溢出风险的
 b. 同为负数,如果有Tmin,则会有天然的大小关系。
 如果没有Tmin则可以正常比较。
同样地,我们对于条件分类使用之前在conditional中使用过的通道的方法。
先设置一下辅助参数如下:
int sx=x>>31;
int sy=y>>31;
int Tmin=1<<31;
int ANS;
     
      
       
        
         x
        
        
         ≤
        
        
         y
        
       
       
        x \le y
       
      
     x≤y 可能会有的几种情况:
 Case1:
     
      
       
        
         x
        
        
         <
        
        
         0
        
        
        
         且
        
        
        
         y
        
        
         ≥
        
        
         0
        
       
       
        x < 0\quad 且\quad y\ge0
       
      
     x<0且y≥0
 这种情况直接返回1
int entry1= sx & !sy;
ANS = entry1 & 1;
Case2:
     
      
       
        
         x
        
        
         ≥
        
        
         0
        
        
        
         且
        
        
        
         y
        
        
         ≥
        
        
         0
        
       
       
        x \ge 0\quad 且\quad y\ge0
       
      
     x≥0且y≥0
 直接安全取负,判断是否小于0就可以了
int entry2= !sx & !sy;
ANS |= entry2 & !((y+~x+1)>>31);
Case3:
     
      
       
        
         x
        
        
         <
        
        
         0
        
        
        
         且
        
        
        
         y
        
        
         <
        
        
         0
        
       
       
        x < 0\quad 且\quad y<0
       
      
     x<0且y<0
 因为要对x取反,那么需要知道x是否为Tmin。
 若x==Tmin,则直接return 1;
 若不为Tmin,那直接判断就好。
int entry3= sx & sy;
ANS |= entry3 & (!(x^Tmin) | !((y+~x+1)>>31));
最终为:
int isLessOrEqual(int x, int y) {
	int sx=x>>31;
	int sy=y>>31;
	int Tmin=1<<31;
	int ANS=0;
	int cp_xy=!((y+~x+1)>>31);
	
	int entry1= sx & !sy;
	ANS |= entry1 & 1;
	
	int entry2= !sx & !sy;
	ANS |= entry2 & cp_xy;
	
	int entry3= sx & sy;
	ANS |= entry3 & (!(x^Tmin) | cp_xy);
	
	return ANS;
}
第九题
/* 
 * 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 
 */
只有当x==0时,才会输出1;
 解这道题,需要利用0的独特性质:
 
     
      
       
        
         N
        
        
         u
        
        
         m
        
        
         ×
        
        
         N
        
        
         u
        
        
         
          m
         
         
          
           a
          
          
           d
          
          
           v
          
          
           e
          
          
           r
          
          
           s
          
          
           e
          
         
        
        
         ≥
        
        
         0
        
       
       
         Num\times Num_{adverse} \ge0 
       
      
     Num×Numadverse≥0
 即Num与它的加法逆元同号。
 但是需要注意的是,满足上述的等式的 Num 有两个,Tmin 与 0;
主要思路:
- 确定x等于它的加法逆元
- 排除Tmin的情况
int logicalNeg(int x) {
  int s1=(~((x ^ (~x+1)) >>31)) & 1;
  int s2=(~(x>>31)) & 1;
  return s1 & s2;
}
第十题
/* 
 *  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
 */
这道题真是二分查找思想的极致运用了。
 首先,要先理解数据,比如,0x11111事实上只用一位就可以表示。
 做一个小小的示例:
 
     
      
       
        
         000
        
        
         1
        
        
          
        
        
         111
        
        
         0
        
        
          
        
        
         0000
        
        
          
        
        
         0000
        
        
          
        
        
         |
        
        
          
        
        
         0000
        
        
          
        
        
         0000
        
        
          
        
        
         0000
        
        
          
        
        
         000
        
        
         
          0
         
         
          
           b
          
          
           i
          
          
           n
          
          
           a
          
          
           r
          
          
           y
          
         
        
       
       
         000\textbf1\ \textbf{111}0\ 0000\ 0000\ \textbf|\ 0000\ 0000\ 0000\ 0000_{binary} 
       
      
     0001 1110 0000 0000 | 0000 0000 0000 0000binary
 与
 
     
      
       
        
         111
        
        
         0
        
        
          
        
        
         000
        
        
         1
        
        
          
        
        
         1111
        
        
          
        
        
         1111
        
        
          
        
        
         |
        
        
          
        
        
         1111
        
        
          
        
        
         1111
        
        
          
        
        
         1111
        
        
          
        
        
         111
        
        
         
          1
         
         
          
           b
          
          
           i
          
          
           n
          
          
           a
          
          
           r
          
          
           y
          
         
        
       
       
         111\textbf0\ \textbf{000}1\ 1111\ 1111 \ \textbf|\ 1111\ 1111\ 1111\ 1111_{binary} 
       
      
     1110 0001 1111 1111 | 1111 1111 1111 1111binary
 会得到一样的答案,但前者会明显更好处理。
 那不妨将所有的负数都做一次取反,而正数则保持不变。
int s=x>>31;
x= s^x;
这做法有点奇妙,如果x为负数,则s = 
    
     
      
       
        0
       
       
        x
       
       
        F
       
       
        F
       
       
        F
       
       
        F
       
       
        F
       
       
        F
       
       
        F
       
       
        F
       
      
      
       0xFFFFFFFF
      
     
    0xFFFFFFFF,s^x就等价于~x
 如果x为正数,则s=
    
     
      
       
        0
       
       
        x
       
       
        00000000
       
      
      
       0x00000000
      
     
    0x00000000,此时s^x等价于啥也不干。
做完这个处理之后,就是本题的精华所在了。
 先将x分为上下16位,若上16位已被使用,则将其左移16位,若没有,则啥也不干。
 以这种处理方式会发现,问题被缩小了,从求解32位数需要的实际位数,变成了求解16位数需要的实际位数再加上16或是0(看情况)。以这种方式一次向下查找。
需要注意,我们找的位置是最大权重的bit所在位,所以最后的答案应该加二,但是0,-1的情况就被忽略了,因此要分一次类,然后依然用通道法完成。
int howManyBits(int x) {
 int s=x>>31;
 x= s^x;
 
 int bit_16=!!(x>>16);
 x=x>>(bit_16<<4);
 
 int bit_8=!!(x>>8);
 x=x>>(bit_8<<3);
 
 int bit_4=!!(x>>4);
 x=x>>(bit_4<<2);
 
 int bit_2=!!(x>>2);
 x=x>>(bit_2<<1);
 
 int bit_1=!!(x>>1);
 x=x>>(bit_1<<0);
 
 int ck=(!x) | (!(~x));
 ck=(ck<<31)>>31;
 
 int sd_ans=(bit_16<<4)+(bit_8<<3)+(bit_4<<2)+(bit_2<<1)+(bit_1)+2;
 
 return (ck & 1) | ((~ck) & sd_ans);
}
Float Part
背景知识:
 
     
      
       
        
         
          
           
            
             u
            
            
             f
            
            
             =
            
            
             0
            
            
             x
            
            
             
              0
             
            
            
             
              100
             
             
                
             
             
              0000
             
             
                
             
             
              1
             
            
            
             
              101
             
             
                
             
             
              0000
             
             
               
             
             
              ∣
             
             
               
             
             
              0000
             
             
                
             
             
              0000
             
             
                
             
             
              0000
             
             
                
             
             
              0000
             
            
           
          
         
        
        
         
          
           
            
             
             
              
              
               
                23
               
              
             
            
            
            
                
           
          
         
        
       
       
         \begin{matrix} uf=0x {\color{Red} 0} {\color{Green}100\ \ 0000\ \ 1 } {\color{Violet} 101\ \ 0000\ |\ 0000\ \ 0000\ \ 0000\ \ 0000} \\ _{_{{\color{Green}23}}}\qquad\qquad\qquad\;\; \end{matrix} 
       
      
     uf=0x0100  0000  1101  0000 ∣ 0000  0000  0000  000023
 其中红色为sign bits,
 绿色为exp bits,
 紫色为frac bits。
其实对于计算机来说,数据都只是对字段的某种理解方式,如果uf为int,那么a就是 108842188 8 d e c 1088421888_{dec} 1088421888dec,但 uf 若为float,那么 uf 就是 6.5 6.5 6.5。(详见CSAPP Chapter 2)
对于浮点数的处理,分为三种情况:
 1,Normal: 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        ≠
       
       
        0
       
      
      
       exp\ne0
      
     
    exp=0 && 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        ≠
       
       
        255
       
      
      
       exp\ne255
      
     
    exp=255
 2,Denormal: 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        =
       
       
        0
       
      
      
       exp=0
      
     
    exp=0
 1,NaN: 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        =
       
       
        255
       
      
      
       exp=255
      
     
    exp=255
第十一题
/* 
 * 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 int s=(uf>>31);
  unsigned int exp=(uf<<1)>>24;
  unsigned int frac=(uf<<9)>>9;
先把数据按照字段切割如上。
// exp==255
if(!(exp^255)) return ans1;
// exp==0 && frac==0
else if(!frac && !exp) return ans2;
// exp==0 && frac!=0
else if(!exp) return ans3;
// exp!=0 && exp!=255
return ans4;
对于代码中的第一个情况,即 e x p = 255 exp=255 exp=255,按照要求NaN原样返回,而 2 ⋅ i n f i n i t e 2\cdot infinite 2⋅infinite 仍然是 i n f i n i t e infinite infinite,所以: a n s 1 = u f ; ans1=uf; ans1=uf;
对于代码中的第二个情况,即 e x p = 0 exp=0 exp=0 && f r a c = 0 frac=0 frac=0,因为 0 × 2 = 0 0\times2=0 0×2=0,所以: a n s 2 = u f ; ans2=uf; ans2=uf;
对于代码中的第三个情况,即 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        =
       
       
        0
       
      
      
       exp=0
      
     
    exp=0 && 
    
     
      
       
        f
       
       
        r
       
       
        a
       
       
        c
       
       
        ≠
       
       
        0
       
      
      
       frac\ne0
      
     
    frac=0,
 
     
      
       
        
         a
        
        
         =
        
        
         (
        
        
         −
        
        
         1
        
        
         
          )
         
         
          s
         
        
        
         ⋅
        
        
         
          2
         
         
          
           e
          
          
           x
          
          
           p
          
          
           −
          
          
           b
          
          
           i
          
          
           a
          
          
           s
          
         
        
        
         ⋅
        
        
         (
        
        
         0
        
        
         .
        
        
         
          f
         
         
          22
         
        
        
         
          f
         
         
          21
         
        
        
         …
        
        
         
          f
         
         
          0
         
        
        
         )
        
       
       
         a=(-1)^{s}\cdot 2^{exp-bias}\cdot(0\textbf.f_{22}f_{21}…f_{0}) 
       
      
     a=(−1)s⋅2exp−bias⋅(0.f22f21…f0)
 所以乘以二后的结果可以表示为:
 
     
      
       
        
         2
        
        
         ⋅
        
        
         a
        
        
         =
        
        
         (
        
        
         −
        
        
         1
        
        
         
          )
         
         
          s
         
        
        
         ⋅
        
        
         
          2
         
         
          
           e
          
          
           x
          
          
           p
          
          
           −
          
          
           b
          
          
           i
          
          
           a
          
          
           s
          
         
        
        
         ⋅
        
        
         (
        
        
         
          f
         
         
          22
         
        
        
         .
        
        
         
          f
         
         
          21
         
        
        
         …
        
        
         
          f
         
         
          0
         
        
        
         0
        
        
         )
        
       
       
         2\cdot a=(-1)^{s}\cdot 2^{exp-bias}\cdot (f_{22}\textbf.f_{21}…f_{0}0) 
       
      
     2⋅a=(−1)s⋅2exp−bias⋅(f22.f21…f00)
 因此,就算frac<<1导致了越界,会发现这正好就是我们想要的结果,因为情况由Normal变为了Denormal,但这两种情况计算exp的不同,却恰恰导致了最终结果的相同。
 
     
      
       
        
         a
        
        
         n
        
        
         s
        
        
         3
        
        
         =
        
        
         (
        
        
         s
        
        
         <
        
        
         <
        
        
         31
        
        
         )
        
        
         +
        
        
         (
        
        
         f
        
        
         r
        
        
         a
        
        
         c
        
        
         <
        
        
         <
        
        
         1
        
        
         )
        
        
         ;
        
       
       
        ans3=(s<<31) + (frac<<1);
       
      
     ans3=(s<<31)+(frac<<1);
 对于代码中的第四个情况,即 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        ≠
       
       
        0
       
      
      
       exp\ne0
      
     
    exp=0 && 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        ≠
       
       
        255
       
      
      
       exp\ne255
      
     
    exp=255,
 这种情况就是最直接的理解,
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        =
       
       
        e
       
       
        x
       
       
        p
       
       
        +
       
       
        1
       
      
      
       exp=exp+1
      
     
    exp=exp+1 即可。
 
     
      
       
        
         a
        
        
         n
        
        
         s
        
        
         4
        
        
         =
        
        
         (
        
        
         s
        
        
         <
        
        
         <
        
        
         31
        
        
         )
        
        
         +
        
        
         [
        
        
         (
        
        
         e
        
        
         x
        
        
         p
        
        
         +
        
        
         1
        
        
         )
        
        
         <
        
        
         <
        
        
         23
        
        
         ]
        
        
         +
        
        
         f
        
        
         r
        
        
         a
        
        
         c
        
        
         ;
        
       
       
        ans4=(s<<31) + [(exp+1)<<23] + frac;
       
      
     ans4=(s<<31)+[(exp+1)<<23]+frac;
最终程序为:
unsigned floatScale2(unsigned uf) {
  unsigned int s=(uf>>31);
  unsigned int exp=(uf<<1)>>24;
  unsigned int frac=(uf<<9)>>9;
  // exp == 255
  if(!(exp^255)) return uf;
  
  // exp == 0   && frac == 0
  else if(!frac && !exp) return uf;
  // exp == 0   && frac != 0
  else if(!exp) return (s<<31)+(frac<<1);
  // 0<exp<255
  else return (s<<31)+((exp+1)<<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) {
  unsigned int s=(uf>>31);
  unsigned int exp=(uf<<1)>>24;
  unsigned int frac=(uf<<9)>>9;
  ……
}
还是分类讨论:
 1,Normal: 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        ≠
       
       
        0
       
      
      
       exp\ne0
      
     
    exp=0 && 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        ≠
       
       
        255
       
      
      
       exp\ne255
      
     
    exp=255
 2,Denormal: 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        =
       
       
        0
       
      
      
       exp=0
      
     
    exp=0
 1,NaN or Infinite: 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        =
       
       
        255
       
      
      
       exp=255
      
     
    exp=255
  ……
  //exp==255 (NaN or Infinite)
  if(!(exp^255)) return ans1
  //exp==0
  else if(!exp) return ans2;
  
  //0<exp<255 (normal case)
  else ans3;
}
Case 1: 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        =
       
       
        255
       
      
      
       exp=255
      
     
    exp=255
 按照题意,直接返回0x80000000u。
 Case 2: 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        =
       
       
        0
       
      
      
       exp=0
      
     
    exp=0
 因为exp若为0至多 
    
     
      
       
        (
       
       
        
         1
        
        
         2
        
       
       
        
         )
        
        
         126
        
       
      
      
       (\frac{1}{2})^{126}
      
     
    (21)126,直接返回0x0。
 Case 3: 
    
     
      
       
        0
       
       
        <
       
       
        e
       
       
        x
       
       
        p
       
       
        <
       
       
        255
       
      
      
       0<exp<255
      
     
    0<exp<255
 此时可以把 uf变为 
    
     
      
       
        (
       
       
        1
       
       
        .
       
       
        
         f
        
        
         22
        
       
       
        
         f
        
        
         21
        
       
       
        
         f
        
        
         20
        
       
       
        …
       
       
        
         f
        
        
         0
        
       
       
        )
       
       
        <
       
       
        <
       
       
        (
       
       
        e
       
       
        x
       
       
        p
       
       
        −
       
       
        b
       
       
        i
       
       
        a
       
       
        s
       
       
        )
       
      
      
       (1\textbf.f_{22}f_{21}f_{20}…f_{0})<<(exp-bias)
      
     
    (1.f22f21f20…f0)<<(exp−bias)
比如 
    
     
      
       
        e
       
       
        x
       
       
        p
       
       
        −
       
       
        b
       
       
        i
       
       
        a
       
       
        s
       
       
        =
       
       
        2
       
      
      
       exp-bias=2
      
     
    exp−bias=2:
 此时,
    
     
      
       
        u
       
       
        f
       
       
        =
       
       
        1
       
       
        
         f
        
        
         22
        
       
       
        
         f
        
        
         21
        
       
       
        .
       
       
        
         f
        
        
         20
        
       
       
        …
       
       
        
         f
        
        
         0
        
       
       
        0
       
       
        
         0
        
        
         
         
          
           b
          
          
           i
          
          
           n
          
          
           a
          
          
           r
          
          
           y
          
         
        
       
      
      
       uf=1f_{22}f_{21}\textbf.f_{20}…f_{0}00_{_{binary}}
      
     
    uf=1f22f21.f20…f000binary
 而转化为int后直接无视小数点后的数字,即
    
     
      
       
        u
       
       
        f
       
       
        =
       
       
        1
       
       
        
         f
        
        
         22
        
       
       
        
         f
        
        
         21
        
       
      
      
       uf=1f_{22}f_{21}
      
     
    uf=1f22f21
- 但同样要注意细节,若
     
      
       
        
         u
        
        
         f
        
        
         =
        
        
         1
        
        
         
          f
         
         
          22
         
        
        
         
          f
         
         
          21
         
        
        
         
          f
         
         
          20
         
        
        
         …
        
        
         
          f
         
         
          0
         
        
        
         
          0000000
         
        
        
         
          
           0
          
         
         
          
          
           
            b
           
           
            i
           
           
            n
           
           
            a
           
           
            r
           
           
            y
           
          
         
        
       
       
        uf=1f_{22}f_{21}f_{20}…f_{0}{\color{Green}0000000}{\color{Red}0}_{_{binary}}
       
      
     uf=1f22f21f20…f000000000binary,
 那么红色的0会使最终答案越界,因此需要返回0x80000000u。
- 还有 f r a c = 1 f 22 f 21 f 20 … f 0 frac=1f_{22}f_{21}f_{20}…f_{0} frac=1f22f21f20…f0 注意左移或者右移的方向,因为系会将 f r a c > > ( − 2 ) frac>>(-2) frac>>(−2)理解为 f r a c > > 30 frac>>30 frac>>30,而这与我们的本意相悖。
int floatFloat2Int(unsigned uf) {
  unsigned int s=(uf>>31);
  unsigned int exp=(uf<<1)>>24;
  unsigned int frac=(uf<<9)>>9;
  // NaN || infinity
  if(!(exp^255)) return 0x80000000u;
  // denormal case(exp == 0)
  else if(!exp) return 0;
  // normal case(0<exp<255)
  else{
    frac+=(1<<23);
    int bits=(150u-exp);
    // bits<-7(这种情况会使只有0-23位的frac发生溢出)
    if((bits+7)>>31) return 0x80000000u;
    else{
      int tmp;
      // bits小于0
      if(bits>>31) tmp=frac<<((~bits)+1);
      // bits大于31
      else if((32+(~bits))>>31) tmp=0;
      else tmp=frac>>bits;
      return (!s)?tmp:(~tmp)+1;
    }
  }
}
第十三题
/* 
 * 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
 */
     
      
       
        
         
          
           
            
             a
            
            
             =
            
            
             0
            
            
             x
            
            
             
              0
             
            
            
             
              000
             
             
                
             
             
              0000
             
             
                
             
             
              0
             
            
            
             
              000
             
             
                
             
             
              0000
             
             
               
             
             
              ∣
             
             
               
             
             
              0000
             
             
                
             
             
              0000
             
             
                
             
             
              0000
             
             
                
             
             
              0001
             
            
           
          
         
        
        
         
          
           
            
             
             
              
              
               
                23
               
              
             
            
            
            
                
           
          
         
        
       
       
         \begin{matrix} a=0x {\color{Red} 0} {\color{Green}000\ \ 0000\ \ 0 } {\color{Violet} 000\ \ 0000\ |\ 0000\ \ 0000\ \ 0000\ \ 0001} \\ _{_{{\color{Green}23}}}\qquad\qquad\qquad\;\; \end{matrix} 
       
      
     a=0x0000  0000  0000  0000 ∣ 0000  0000  0000  000123
 Case1:当 
    
     
      
       
        x
       
       
        <
       
       
        −
       
       
        (
       
       
        126
       
       
        +
       
       
        23
       
       
        )
       
      
      
       x<-(126+23)
      
     
    x<−(126+23),
 
     
      
       
        
         
          2
         
         
          x
         
        
        
         <
        
        
         0
        
        
         x
        
        
         
          0
         
        
        
         
          000
         
         
            
         
         
          0000
         
         
            
         
         
          0
         
        
        
         
          000
         
         
            
         
         
          0000
         
         
           
         
         
          ∣
         
         
           
         
         
          0000
         
         
            
         
         
          0000
         
         
            
         
         
          0000
         
         
            
         
         
          0001
         
        
       
       
        2^{x}<0x {\color{Red} 0} {\color{Green}000\ \ 0000\ \ 0 } {\color{Violet} 000\ \ 0000\ |\ 0000\ \ 0000\ \ 0000\ \ 0001}
       
      
     2x<0x0000  0000  0000  0000 ∣ 0000  0000  0000  0001,即float能表示的最小数。
 此时视为过小,按要求需要返回0
 
     
      
       
        
         ∴
        
        
         a
        
        
         n
        
        
         s
        
        
         1
        
        
         =
        
        
         0
        
       
       
        \therefore ans1=0
       
      
     ∴ans1=0
Case2:当 
    
     
      
       
        −
       
       
        (
       
       
        126
       
       
        +
       
       
        23
       
       
        )
       
       
        ≤
       
       
        x
       
       
        ≤
       
       
        −
       
       
        127
       
      
      
       -(126+23)\le x \le-127
      
     
    −(126+23)≤x≤−127,
 做一下分解:
 
     
      
       
        
         
          
           
            
             
              2
             
             
              x
             
            
            
             =
            
            
             
              2
             
             
              
               −
              
              
               126
              
              
               +
              
              
               (
              
              
               −
              
              
               b
              
              
               i
              
              
               t
              
              
               s
              
              
               )
              
             
            
           
          
         
        
        
         
          
           
            
             =
            
            
             
              2
             
             
              E
             
            
            
             ×
            
            
             M
             
           
          
         
        
       
       
         \begin{matrix} 2^{x}=2^{-126+(-bits)} \\ =2^{E}\times M \, \end{matrix} 
       
      
     2x=2−126+(−bits)=2E×M
 所以 
     
      
       
        
         b
        
        
         i
        
        
         t
        
        
         s
        
        
         =
        
        
         −
        
        
         126
        
        
         −
        
        
         x
        
       
       
        bits=-126-x
       
      
     bits=−126−x
     
      
       
        
         ∴
        
        
         a
        
        
         n
        
        
         s
        
        
         2
        
        
         =
        
        
         (
        
        
         1
        
        
         <
        
        
         <
        
        
         23
        
        
         )
        
        
         >
        
        
         >
        
        
         b
        
        
         i
        
        
         t
        
        
         s
        
       
       
        \therefore ans2=(1<<23)>>bits
       
      
     ∴ans2=(1<<23)>>bits
 Case3:当 
    
     
      
       
        −
       
       
        126
       
       
        ≤
       
       
        x
       
       
        ≤
       
       
        (
       
       
        254
       
       
        −
       
       
        127
       
       
        )
       
      
      
       -126\le x \le(254-127)
      
     
    −126≤x≤(254−127),
 此时
 
     
      
       
        
         
          2
         
         
          x
         
        
        
         =
        
        
         
          2
         
         
          
           e
          
          
           x
          
          
           p
          
          
           −
          
          
           127
          
         
        
       
       
         2^{x}=2^{exp-127} 
       
      
     2x=2exp−127
 
     
      
       
        
         ∴
        
        
         e
        
        
         x
        
        
         p
        
        
         =
        
        
         x
        
        
         +
        
        
         127
        
       
       
         \therefore exp=x +127 
       
      
     ∴exp=x+127
 
     
      
       
        
         ∴
        
        
         a
        
        
         n
        
        
         s
        
        
         3
        
        
         =
        
        
         (
        
        
         e
        
        
         x
        
        
         p
        
        
         <
        
        
         <
        
        
         23
        
        
         )
        
       
       
        \therefore ans3=(exp<<23)
       
      
     ∴ans3=(exp<<23)
Case4:当 
    
     
      
       
        x
       
       
        >
       
       
        (
       
       
        254
       
       
        −
       
       
        127
       
       
        )
       
      
      
       x>(254-127)
      
     
    x>(254−127),
 
     
      
       
        
         ∴
          
        
         
          2
         
         
          x
         
        
        
         >
        
        
         0
        
        
         x
        
        
         
          0
         
        
        
         
          111
         
         
            
         
         
          1111
         
         
            
         
         
          0
         
        
        
         
          000
         
         
            
         
         
          0000
         
         
           
         
         
          ∣
         
         
           
         
         
          0000
         
         
            
         
         
          0000
         
         
            
         
         
          0000
         
         
            
         
         
          0000
         
        
       
       
        \therefore \;2^{x}>0x {\color{Red} 0} {\color{Green}111\ \ 1111\ \ 0 } {\color{Violet} 000\ \ 0000\ |\ 0000\ \ 0000\ \ 0000\ \ 0000}
       
      
     ∴2x>0x0111  1111  0000  0000 ∣ 0000  0000  0000  0000
 按照题意视为过大,返回 inf,即 
    
     
      
       
        0
       
       
        x
       
       
        
         0
        
       
       
        
         111
        
        
           
        
        
         1111
        
        
           
        
        
         1
        
       
       
        
         000
        
        
           
        
        
         0000
        
        
          
        
        
         ∣
        
        
          
        
        
         0000
        
        
           
        
        
         0000
        
        
           
        
        
         0000
        
        
           
        
        
         0000
        
       
      
      
       0x {\color{Red} 0} {\color{Green}111\ \ 1111\ \ 1 } {\color{Violet} 000\ \ 0000\ |\ 0000\ \ 0000\ \ 0000\ \ 0000}
      
     
    0x0111  1111  1000  0000 ∣ 0000  0000  0000  0000
∴ a n s 4 = ( 255 < < 23 ) \therefore ans4=(255<<23) ∴ans4=(255<<23)
unsigned floatPower2(int x) {
  unsigned int exp=0;
  if(x+149>>31) return exp;
  else if((128 + ~x)>>31){
    exp=255;
    return exp<<23;
  }
  else if(x+126>>31){
    unsigned int frac=1<<23;
    int bits=~(x+126)+1;
    return frac>>bits;
  }
  else{
    exp=x+127;
    return exp<<23;
  }
}










