• CS:APP datalab


    做得有点慢,位运算确实不太容易想到……

    写出来的代码如果没有注释也不容易看懂。

      1 /* 
      2 * CS:APP Data Lab 
      3 * 
      4 * <Please put your name and userid here>
      5 * 
      6 * bits.c - Source file with your solutions to the Lab.
      7 *          This is the file you will hand in to your instructor.
      8 *
      9 * WARNING: Do not include the <stdio.h> header; it confuses the dlc
     10 * compiler. You can still use printf for debugging without including
     11 * <stdio.h>, although you might get a compiler warning. In general,
     12 * it's not good practice to ignore compiler warnings, but in this
     13 * case it's OK.  
     14 */
     15 #if 0
     16 /*
     17 * Instructions to Students:
     18 *
     19 * STEP 1: Read the following instructions carefully.
     20 */
     21 You will provide your solution to the Data Lab by
     22 editing the collection of functions in this source file.
     23     INTEGER CODING RULES:
     24 Replace the "return" statement in each function with one
     25 or more lines of C code that implements the function. Your code 
     26 must conform to the following style:
     27 int Funct(arg1, arg2, ...) {
     28     /* brief description of how your implementation works */
     29     int var1 = Expr1;
     30     ...
     31         int varM = ExprM;
     32     varJ = ExprJ;
     33     ...
     34         varN = ExprN;
     35     return ExprR;
     36 }
     37 Each "Expr" is an expression using ONLY the following:
     38 1. Integer constants 0 through 255 (0xFF), inclusive. You are
     39 not allowed to use big constants such as 0xffffffff.
     40     2. Function arguments and local variables (no global variables).
     41     3. Unary integer operations ! ~
     42 4. Binary integer operations & ^ | + << >>
     43     Some of the problems restrict the set of allowed operators even further.
     44     Each "Expr" may consist of multiple operators. You are not restricted to
     45 one operator per line.
     46     You are expressly forbidden to:
     47 1. Use any control constructs such as if, do, while, for, switch, etc.
     48     2. Define or use any macros.
     49     3. Define any additional functions in this file.
     50     4. Call any functions.
     51     5. Use any other operations, such as &&, ||, -, or ?:
     52 6. Use any form of casting.
     53     7. Use any data type other than int.  This implies that you
     54 cannot use arrays, structs, or unions.
     55     You may assume that your machine:
     56 1. Uses 2s complement, 32-bit representations of integers.
     57     2. Performs right shifts arithmetically.
     58     3. Has unpredictable behavior when shifting an integer by more
     59 than the word size.
     60     EXAMPLES OF ACCEPTABLE CODING STYLE:
     61 /*
     62 * pow2plus1 - returns 2^x + 1, where 0 <= x <= 31
     63 */
     64 int pow2plus1(int x) {
     65     /* exploit ability of shifts to compute powers of 2 */
     66     return (1 << x) + 1;
     67 }
     68 /*
     69 * pow2plus4 - returns 2^x + 4, where 0 <= x <= 31
     70 */
     71 int pow2plus4(int x) {
     72     /* exploit ability of shifts to compute powers of 2 */
     73     int result = (1 << x);
     74     result += 4;
     75     return result;
     76 }
     77 FLOATING POINT CODING RULES
     78 For the problems that require you to implent floating-point operations,
     79 the coding rules are less strict.  You are allowed to use looping and
     80 conditional control.  You are allowed to use both ints and unsigneds.
     81     You can use arbitrary integer and unsigned constants.
     82     You are expressly forbidden to:
     83 1. Define or use any macros.
     84     2. Define any additional functions in this file.
     85     3. Call any functions.
     86     4. Use any form of casting.
     87     5. Use any data type other than int or unsigned.  This means that you
     88 cannot use arrays, structs, or unions.
     89     6. Use any floating point data types, operations, or constants.
     90     NOTES:
     91 1. Use the dlc (data lab checker) compiler (described in the handout) to 
     92 check the legality of your solutions.
     93     2. Each function has a maximum number of operators (! ~ & ^ | + << >>)
     94     that you are allowed to use for your implementation of the function. 
     95         The max operator count is checked by dlc. Note that '=' is not 
     96 counted; you may use as many of these as you want without penalty.
     97     3. Use the btest test harness to check your functions for correctness.
     98         4. Use the BDD checker to formally verify your functions
     99 5. The maximum number of ops for each function is given in the
    100 header comment for each function. If there are any inconsistencies 
    101 between the maximum ops in the writeup and in this file, consider
    102 this file the authoritative source.
    103     /*
    104 * STEP 2: Modify the following functions according the coding rules.
    105 * 
    106 *   IMPORTANT. TO AVOID GRADING SURPRISES:
    107 *   1. Use the dlc compiler to check that your solutions conform
    108 *      to the coding rules.
    109 *   2. Use the BDD checker to formally verify that your solutions produce 
    110 *      the correct answers.
    111 */
    112     #endif
    113     /* 
    114 * bitAnd - x&y using only ~ and | 
    115 *   Example: bitAnd(6, 5) = 4
    116 *   Legal ops: ~ |
    117 *   Max ops: 8
    118 *   Rating: 1
    119 */
    120     int bitAnd(int x, int y) {
    121     //德摩根律
    122     return ~(~x|~y);
    123 }
    124 /* 
    125 * getByte - Extract byte n from word x
    126 *   Bytes numbered from 0 (LSB) to 3 (MSB)
    127 *   Examples: getByte(0x12345678,1) = 0x56
    128 *   Legal ops: ! ~ & ^ | + << >>
    129 *   Max ops: 6
    130 *   Rating: 2
    131 */
    132 int getByte(int x, int n) {
    133     
    134     x=x>>(n<<3);
    135     x=0xFF&x;
    136     return x;
    137 }
    138 /* 
    139 * logicalShift - shift x to the right by n, using a logical shift
    140 *   Can assume that 0 <= n <= 31
    141 *   Examples: logicalShift(0x87654321,4) = 0x08765432
    142 *   Legal ops: ! ~ & ^ | + << >>
    143 *   Max ops: 20
    144 *   Rating: 3 
    145 */
    146 int logicalShift(int x, int n) {
    147     /* if x is neg, will add 1s on left , change them to 0.
    148     & a number as 00000...111111
    149     1<<31->0x80000000 right shift to get 1111...000 then ~
    150     if n==0 , left shift 1 -> 0, else left shift 0
    151     the number right shift (n-1) bits(n!=0, right n ,then left 1) 
    152     or 0 bit(right 0 left 0). */
    153     /*at first, tried change sign ,then shift, failed at 0*/
    154     
    155     return (x>>n)&~(1<<31<<!n>>n<<!!n);
    156 }
    157 /*
    158 * bitCount - returns count of number of 1's in word
    159 *   Examples: bitCount(5) = 2, bitCount(7) = 3
    160 *   Legal ops: ! ~ & ^ | + << >>
    161 *   Max ops: 40
    162 *   Rating: 4
    163 */
    164 int bitCount(int x) {
    165     //divide conquer
    166     //due to limiting const(max 0xff), my ops over 40, answer from cnblosg:liqiuhao
    167     int mask1 = (((((0x55 << 8) + 0x55) << 8) + 0x55) << 8) + 0x55;
    168     int mask2 = (((((0x33 << 8) + 0x33) << 8) + 0x33) << 8) + 0x33;
    169     int mask3 = (((((0x0f << 8) + 0x0f) << 8) + 0x0f) << 8) + 0x0f;
    170     x = (x & mask1) + ((x >>1) & mask1);
    171     x = (x & mask2) + ((x >>2) & mask2);
    172     x = (x & mask3) + ((x >>4) & mask3);
    173     x = x + (x>>8);//4 bytes:3,2,1,0->3,3+2,2+1,1+0
    174     x = x + (x>>16);//->3,3+2,3+2+1,3+2+1+0
    175     return x & 0x3F;//max=0x0010,0000  thus & 0x0011,1111
    176 }
    177 /* 
    178 * bang - Compute !x without using !
    179 *   Examples: bang(3) = 0, bang(0) = 1
    180 *   Legal ops: ~ & ^ | + << >>
    181 *   Max ops: 12
    182 *   Rating: 4 
    183 */
    184 int bang(int x) {
    185     return (((~x+1)|x)>>31)+1;
    186 }
    187 /* 
    188 * tmin - return minimum two's complement integer 
    189 *   Legal ops: ! ~ & ^ | + << >>
    190 *   Max ops: 4
    191 *   Rating: 1
    192 */
    193 int tmin(void) {
    194     return 1<<31;
    195 }
    196 /* 
    197 * fitsBits - return 1 if x can be represented as an 
    198 *  n-bit, two's complement integer.
    199 *   1 <= n <= 32
    200 *   Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
    201 *   Legal ops: ! ~ & ^ | + << >>
    202 *   Max ops: 15
    203 *   Rating: 2
    204 */
    205 int fitsBits(int x, int n) {
    206     //didn't make out, answer from cnblogs:liqiuhao
    207     int y;
    208     n = ~n + 1;
    209     y = (x << (32 + n)) >> (32 + n);
    210     //shift to most left,truncate 32-n
    211     return !(y ^ x);
    212 }
    213 /* 
    214 * divpwr2 - Compute x/(2^n), for 0 <= n <= 30
    215 *  Round toward zero
    216 *   Examples: divpwr2(15,1) = 7, divpwr2(-33,4) = -2
    217 *   Legal ops: ! ~ & ^ | + << >>
    218 *   Max ops: 15
    219 *   Rating: 2
    220 */
    221 int divpwr2(int x, int n) {
    222     /*
    223     pos:x>>n
    224     neg:(x+2^n-1)/2^n, (x + (1<<n)-1) >> n
    225     */
    226     int mask=((1<<n)+~0)&x>>31; //>> prior of & ,
    227     return (x + mask) >> n;
    228 }
    229 /* 
    230 * negate - return -x 
    231 *   Example: negate(1) = -1.
    232 *   Legal ops: ! ~ & ^ | + << >>
    233 *   Max ops: 5
    234 *   Rating: 2
    235 */
    236 int negate(int x) {
    237     return ~x+1;
    238 }
    239 /* 
    240 * isPositive - return 1 if x > 0, return 0 otherwise 
    241 *   Example: isPositive(-1) = 0.
    242 *   Legal ops: ! ~ & ^ | + << >>
    243 *   Max ops: 8
    244 *   Rating: 3
    245 */
    246 int isPositive(int x) {
    247     return (!!x)&((x>>31)+1);// 0
    248 }
    249 /* 
    250 * isLessOrEqual - if x <= y  then return 1, else return 0 
    251 *   Example: isLessOrEqual(4,5) = 1.
    252 *   Legal ops: ! ~ & ^ | + << >>
    253 *   Max ops: 24
    254 *   Rating: 3
    255 */
    256 int isLessOrEqual(int x, int y) {
    257     /*
    258     1. x has same sign with y(wont overflow), and y-x>=0
    259     2. different sign,y is pos.
    260     */
    261     int sum=((~x+1+y)>>31)+1;//y-x>=0, (pos>>31)+1=1,(neg>>31)+1=0
    262     //int xsign=(x>>31)+1;
    263     int ysign=(y>>31)+1;
    264     int same=((x^y)>>31)+1;
    265     return (same&sum)|(!same&ysign);
    266 }
    267 /*
    268 * ilog2 - return floor(log base 2 of x), where x > 0
    269 *   Example: ilog2(16) = 4
    270 *   Legal ops: ! ~ & ^ | + << >>
    271 *   Max ops: 90
    272 *   Rating: 4
    273 */
    274 int ilog2(int x) {
    275     //binary search
    276     //1. if in former 16 bits?
    277     int mask0=0xff<<8;
    278     int mask1=(mask0+0xff)<<16;
    279     int res1=!!(mask1&x);//if in?
    280     int shift1=res1<<4;
    281     int res2,res3,res4,res5,shift2,shift3,shift4,shift5,ans;
    282     x=x>>shift1;//mask1>> 0 or 16 bits
    283     //2. 8 bits
    284     res2=!!(mask0&x);
    285     shift2=res2<<3;
    286     x=x>>shift2;
    287     //3. 4bits
    288     res3=!!(0xf0&x);
    289     shift3=res3<<2;
    290     x=x>>shift3;
    291     //4. 2 bits
    292     res4=!!(0xc&x);
    293     shift4=res4<<1;
    294     x=x>>shift4;
    295     //5. 1 bits
    296     res5=!!(0x2&x);
    297     shift5=res5;
    298     ans=shift1+shift2+shift3+shift4+shift5;
    299     return ans;
    300 }
    301 /* 
    302 * float_neg - Return bit-level equivalent of expression -f for
    303 *   floating point argument f.
    304 *   Both the argument and result are passed as unsigned int's, but
    305 *   they are to be interpreted as the bit-level representations of
    306 *   single-precision floating point values.
    307 *   When argument is NaN, return argument.
    308 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
    309 *   Max ops: 10
    310 *   Rating: 2
    311 */
    312 unsigned float_neg(unsigned uf) {
    313     /*
    314     if NaN,return uf,else return -uf
    315     1^A=~A,0^A=A
    316     judge NaN:==0x7fc00000,0xffc00000
    317     */
    318     unsigned mask1=0x80000000;//1<<31;
    319     unsigned mask2=0x7f800000;//=uf<<1;
    320     unsigned mask3=0x007fffff;
    321     unsigned mask4=0x7fc00000;
    322     //if(!((mask2&uf)^mask2)&&(mask3&uf)) successful
    323     if(!((mask4&uf)^mask4))//another way
    324     {return uf;}
    325     else {
    326         uf = uf ^ mask1 ;
    327         return uf;
    328     }
    329 }
    330 /* 
    331 * float_i2f - Return bit-level equivalent of expression (float) x
    332 *   Result is returned as unsigned int, but
    333 *   it is to be interpreted as the bit-level representation of a
    334 *   single-precision floating point values.
    335 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
    336 *   Max ops: 30
    337 *   Rating: 4
    338 */
    339 unsigned float_i2f(int x) {
    340     
    341     if(!x){return 0;}
    342     else{
    343         int exp=~0;
    344         int E;
    345         unsigned mask1=x;
    346         unsigned mask2,mask3;
    347         int shift;
    348         int sign=0x80000000&x;// pos=0, neg=1
    349         if(sign){
    350             mask1=-mask1;
    351         }
    352         mask3=mask2=mask1;
    353         while(mask1){
    354             exp=exp+1;
    355             mask1=mask1>>1;
    356         }
    357         E=exp;
    358         // exp=(exp+0x7f)<<23;
    359         shift=31-E-8;
    360         // mask2=mask2<<(31-exp);
    361         // mask2=mask2>>8;
    362         if(shift>=0){//forgot "="
    363         // left shift
    364             // mask2<<shift;//mdzz, debug for a long time
    365             mask3=mask3<<shift; // fotgot "="
    366         }
    367         else{
    368             /* shift < 0, right shift.deal with round.round to even
    369             if odd,add 0.5 (if deserted frac > 0.5 , +1 ;if = , +1);
    370             if even ,add 0.499...(if deserted frac > 0.5 , +1 ;if = , +0)*/
    371             shift=-shift;
    372             // mask2>>shift;
    373             mask2=mask2>>shift;
    374             mask3+=(1<<(shift-1));
    375             if(mask2&1){
    376             }
    377             else{
    378                 mask3+=-1;
    379             }
    380             mask3=mask3>>shift;
    381         }
    382         exp=((exp+0x7f)<<23)+(mask3>>1);//round may cause overflow
    383         exp=exp&0xff800000; // get rid of influence of adding frac
    384         mask3=mask3&0x7fffff;
    385         return sign|exp|mask3;
    386     }
    387 }
    388 /* 
    389 * float_twice - Return bit-level equivalent of expression 2*f for
    390 *   floating point argument f.
    391 *   Both the argument and result are passed as unsigned int's, but
    392 *   they are to be interpreted as the bit-level representation of
    393 *   single-precision floating point values.
    394 *   When argument is NaN, return argument
    395 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
    396 *   Max ops: 30
    397 *   Rating: 4
    398 */
    399 unsigned float_twice(unsigned uf) {
    400     /*
    401     1. special:inf or NaN
    402     2. denorm 
    403     2.1 0
    404     2.2 close to 0
    405     3. norm ,exp++*/
    406     unsigned res;
    407     int mask1=uf&0x7f800000;
    408     int sign = uf&0x80000000;
    409     if(!(mask1^0x7f800000)){//exp all 1
    410         res= uf;
    411     }
    412     else if(!(mask1)){//exp all 0
    413         if(!(uf&0x7fffffff)){// 0
    414             res= uf;
    415         }
    416         else{
    417             res=uf<<1;
    418             res=res|sign;
    419         }
    420     }
    421     else{
    422         res = uf + 0x800000;
    423     }
    424     return res;
    425 }
    View Code

    //

  • 相关阅读:
    Selenium笔记(三)--WebDriver 等待、支持的类、javaScript警告框、提示框、确认框、Http代理、页面加载策略、网络元素、Keyboard;远程WebDriver
    Selenium3+python3自动化(四十八)--阿里云centos7上搭建selenium启动chrome浏览器headless无界面模式
    Selenium3+python3自动化(四十七)--定位的坑:class属性有空格
    Selenium3+python3自动化(四十六)--弹窗处理(PyKeyboard) tab切换,enter回车,输入
    Selenium3+python3自动化(四十五)--弹出框死活定位不到
    Selenium3+python3自动化(四十四)--行为事件(ActionChains)源码详解
    Selenium3+python3自动化(四十三)--爬取我的博客园粉丝的名称,并写入.text文件
    Selenium3+python3自动化(四十二)--批量操作循环点击报错
    Selenium3+python3自动化(四十一)--Chrome浏览器静默模式启动(headless)
    Selenium3+python3自动化(四十)--Chrome正在受到自动软件的控制
  • 原文地址:https://www.cnblogs.com/azureice/p/8424097.html
Copyright © 2020-2023  润新知