213 lab1 datalab

本文提供了一份详细的CS:APPDataLab实验报告,包括按要求完成的各项任务代码及解析,如位运算、浮点数操作等,适用于学习计算机组成原理的同学。

Lab1

第一次做213的lab 呕出一口老血 下面的代码都是运行通过的

/* 
 * CS:APP Data Lab 
 * 
 * <Please put your name and userid here>
 * 
 * bits.c - Source file with your solutions to the Lab.
 *          This is the file you will hand in to your instructor.
 *
 * WARNING: Do not include the <stdio.h> header; it confuses the dlc
 * compiler. You can still use printf for debugging without including
 * <stdio.h>, although you might get a compiler warning. In general,
 * it's not good practice to ignore compiler warnings, but in this
 * case it's OK.  
 */

#if 0
/*
 * Instructions to Students:
 *
 * STEP 1: Read the following instructions carefully.
 */

You will provide your solution to the Data Lab by
editing the collection of functions in this source file.

INTEGER CODING RULES:

  Replace the "return" statement in each function with one
  or more lines of C code that implements the function. Your code 
  must conform to the following style:

  int Funct(arg1, arg2, ...) {
      /* brief description of how your implementation works */
      int var1 = Expr1;
      ...
      int varM = ExprM;

      varJ = ExprJ;
      ...
      varN = ExprN;
      return ExprR;
  }

  Each "Expr" is an expression using ONLY the following:
  1. Integer constants 0 through 255 (0xFF), inclusive. You are
      not allowed to use big constants such as 0xffffffff.
  2. Function arguments and local variables (no global variables).
  3. Unary integer operations ! ~
  4. Binary integer operations & ^ | + << >>

  Some of the problems restrict the set of allowed operators even further.
  Each "Expr" may consist of multiple operators. You are not restricted to
  one operator per line.

  You are expressly forbidden to:
  1. Use any control constructs such as if, do, while, for, switch, etc.
  2. Define or use any macros.
  3. Define any additional functions in this file.
  4. Call any functions.
  5. Use any other operations, such as &&, ||, -, or ?:
  6. Use any form of casting.
  7. Use any data type other than int.  This implies that you
     cannot use arrays, structs, or unions.


  You may assume that your machine:
  1. Uses 2s complement, 32-bit representations of integers.
  2. Performs right shifts arithmetically.
  3. Has unpredictable behavior when shifting an integer by more
     than the word size.

EXAMPLES OF ACCEPTABLE CODING STYLE:
  /*
   * pow2plus1 - returns 2^x + 1, where 0 <= x <= 31
   */
  int pow2plus1(int x) {
     /* exploit ability of shifts to compute powers of 2 */
     return (1 << x) + 1;
  }

  /*
   * pow2plus4 - returns 2^x + 4, where 0 <= x <= 31
   */
  int pow2plus4(int x) {
     /* exploit ability of shifts to compute powers of 2 */
     int result = (1 << x);
     result += 4;
     return result;
  }

FLOATING POINT CODING RULES

For the problems that require you to implent floating-point operations,
the coding rules are less strict.  You are allowed to use looping and
conditional control.  You are allowed to use both ints and unsigneds.
You can use arbitrary integer and unsigned constants.

You are expressly forbidden to:
  1. Define or use any macros.
  2. Define any additional functions in this file.
  3. Call any functions.
  4. Use any form of casting.
  5. Use any data type other than int or unsigned.  This means that you
     cannot use arrays, structs, or unions.
  6. Use any floating point data types, operations, or constants.


NOTES:
  1. Use the dlc (data lab checker) compiler (described in the handout) to 
     check the legality of your solutions.
  2. Each function has a maximum number of operators (! ~ & ^ | + << >>)
     that you are allowed to use for your implementation of the function. 
     The max operator count is checked by dlc. Note that '=' is not 
     counted; you may use as many of these as you want without penalty.
  3. Use the btest test harness to check your functions for correctness.
  4. Use the BDD checker to formally verify your functions
  5. The maximum number of ops for each function is given in the
     header comment for each function. If there are any inconsistencies 
     between the maximum ops in the writeup and in this file, consider
     this file the authoritative source.

/*
 * STEP 2: Modify the following functions according the coding rules.
 * 
 *   IMPORTANT. TO AVOID GRADING SURPRISES:
 *   1. Use the dlc compiler to check that your solutions conform
 *      to the coding rules.
 *   2. Use the BDD checker to formally verify that your solutions produce 
 *      the correct answers.
 */


#endif

以上部分是一些说明和要求
下面开始是练习题

1.bitAnd

/* 
 * bitAnd - x&y using only ~ and | 
 *   Example: bitAnd(6, 5) = 4
 *   Legal ops: ~ |
 *   Max ops: 8
 *   Rating: 1
 */
int bitAnd(int x, int y) {
  return (~((~x)|(~y))); //    ~| == &
}

2.getByte

/* 
 * getByte - Extract byte n from word x
 *   Bytes numbered from 0 (LSB) to 3 (MSB)
 *   Examples: getByte(0x12345678,1) = 0x56
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 6
 *   Rating: 2
 */
int getByte(int x, int n) {
  return (x>>(n<<3))&0xff;//将一个byte单独取出来
}

3.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 
 */向右移动n bit高位补0

int logicalShift(int x, int n) { 
int mask=~(((1<<31)>>n)<<1); //做好一个mask 把右移高位的1去掉
return (x>>n)&mask; 
}

4.bitCount

/*
 * bitCount - returns count of number of 1's in word
 *   Examples: bitCount(5) = 2, bitCount(7) = 3
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 40
 *   Rating: 4
 */计算1的个数
int bitCount(int x) {  
        int result;  
        //int mask1=(0x55)|(0x55<<8)|(0x55<<16)|(0x55<<24); 0101010101... 
        int tmp_mask1=(0x55)|(0x55<<8);  
        int mask1=(tmp_mask1)|(tmp_mask1<<16);  
        //int mask2=(0x33)|(0x33<<8)|(0x33<<16)|(0x33<<24);  001101100110011...
        int tmp_mask2=(0x33)|(0x33<<8);  
        int mask2=(tmp_mask2)|(tmp_mask2<<16);  
        //int mask3=(0x0f)|(0x0f<<8)|(0x0f<<16)|(0x0f<<24);  000011110000111100001111...
        int tmp_mask3=(0x0f)|(0x0f<<8);  
        int mask3=(tmp_mask3)|(tmp_mask3<<16);  
        int mask4=(0xff)|(0xff<<16);  
        int mask5=(0xff)|(0xff<<8);  
        //add every two bits  
        result=(x&mask1)+((x>>1)&mask1);  
        //add every four bits  
        result=(result&mask2)+((result>>2)&mask2);  
        //add every eight bits  
        //result=(result&mask3)+((result>>4)&mask3);  
        result=(result+(result>>4))&mask3;  
        //add every sixteen bits  
        //result=(result&mask4)+((result>>8)&mask4);  
        result=(result+(result>>8))&mask4;  
        //add every thirty two bits  
        //result=(result&mask5)+((result>>16)&mask5);  
        result=(result+(result>>16))&mask5;  
        return result;  
}

5.bang

/* 
 * bang - Compute !x without using !
 *   Examples: bang(3) = 0, bang(0) = 1
 *   Legal ops: ~ & ^ | + << >>
 *   Max ops: 12
 *   Rating: 4 
 */判断x是否为001  x如果非0,则(x|(~x+1)的符号位为1,如果为0,反之
int bang(int x) {
return ~((x|(~x+1))>>31)&0x1; //返回值也是一个int
}

6.tmin

/* 
 * tmin - return minimum two's complement integer 补码最小的整数
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 4
 *   Rating: 1
 */
int tmin(void) {
  return 1<<31;
}
/* 

7.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
 */如果能用n位补码表示
int fitsBits(int x, int n) {
  int sign = x>>31;//all 0 or all 1
  return (~sign & !(x>>(n+~0)))+(sign & !((~x)>>(n+~0))) ;//除去符号位 剩下的数值部分是否能用n-1位来表示
}

8.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) {//要分情况讨论 正数可以直接右移 负数要考虑符号位
    int s=!!(x>>31);//取x的符号位  0 or 1
    int t=(1<<n)+~0;//制作一个只有低n位为1的mask

    int lowx=t&x;//lowx保存x的低n位的值
    return  (x>>n)+((!!lowx)&s);//
}

负数进行右移的时候要进行Biasing 加上2的k次方减1后在右移k位
[草稿](http://img.blog.csdn.net/20160921114817987)

9.negate

/* 
 * negate - return -x 
 *   Example: negate(1) = -1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 5
 *   Rating: 2
 */
int negate(int x) {
  return ~x+1;
}

10.isPositive

/* 
 * isPositive - return 1 if x > 0, return 0 otherwise 
 *   Example: isPositive(-1) = 0.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 8
 *   Rating: 3
 */
int isPositive(int x) {
  int sign = x>>31;
  return (!sign) & (!!x);//仅仅判断符号位是不够的 因为0要单独考虑 不为0且符号位为0才行
}

11.isLessOrEqual

/* 
 * 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) {//consider overflow

int sub=y+(~x+1); //比较数的大小 要考虑符号
int signx = (x >> 31) & 1; 
int signy = (y >> 31) & 1; 
int subsign =!((sub >> 31) & 1);//正的话 1 负的话是0 
return ((signx ^ signy) & signx) + ((signx ^ signy ^ 1) & subsign); 

}

12.ilog2

/*
 * ilog2 - return floor(log base 2 of x), where x > 0
 *   Example: ilog2(16) = 4
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 90
 *   Rating: 4
 */
int ilog2(int x){
  int byte3 = x >> 24;
  int byte2 = (x >> 16) & 0xff;
  int byte1 = (x >> 8) &0xff;
  int byte0 = x &0xff;
// get the four parts 每个byte单独取出来

  int i3 = !!byte3;//see if byte>0 看byte里面是不是为0
  int i2 = i3 | !!byte2;
  int i1 = i2 | !!byte1;
  int i0 = i1 | !!byte0;
  int i = i3 + i2 +i1 +i0 +~0;//注意要减一 得出的结果就是最高位在第几个byte里
  int highbyte = x >> (i <<3);//get highest byte

  int b7 = (highbyte >> 7) & 1;
  int b6 = (highbyte >> 6) & 1;
  int b5 = (highbyte >> 5) & 1;
  int b4 = (highbyte >> 4) & 1;
  int b3 = (highbyte >> 3) & 1;
  int b2 = (highbyte >> 2) & 1;
  int b1 = (highbyte >> 1) & 1;
  int b0 = (highbyte) & 1;//get the number of every bit of highbyte 0 or 1 每一位都get

  int k7 = b7;
  int k6 = k7|b6;
  int k5 = k6|b5;
  int k4 = k5|b4;
  int k3 = k4|b3;
  int k2 = k3|b2;
  int k1 = k2|b1;
  int k0 = k1|b0;
  int k = k7 +k6 +k5 +k4 +k3 +k2+k1+k0+~0; 找到最高位在哪里

  return (i << 3) + k;//
}

13.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
 */  f变-f 这里要考虑NAN的特殊情况
 判断是不是Nan exp(之间8位)部分全为1 数值部分(后23位)不全为0 

//NaN for Not a Nunmber 
unsigned float_neg(unsigned uf) {
  if(   (((uf >> 23 )& 0xff)^0xff) ||  !(uf & ((1<<23)-1))){// two evidence to define if uf is NaN
  uf ^=(1<<31);}//异或 只修改符号位 

 return uf;//如果是Nan 直接return本身
}

14.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
 */强行格式转换 intfloat
unsigned float_i2f(int x) {
   unsigned shiftLeft=0;
    unsigned afterShift, tmp, flag;
    unsigned absX=x;
    unsigned sign=0;
    //special case 考虑正数负数和0
    if (x==0) return 0;
    //if x < 0, sign = 1000...,abs_x = -x
    if (x<0)负数的情况 取符号 取绝对值
    {
        sign=0x80000000;
        absX=-x;
    }
    afterShift=absX;
    //count shift_left and after_shift
    while (1)
    {
        tmp=afterShift;
        afterShift<<=1;
        shiftLeft++;//一直左移 直到出现最高位的1
        if (tmp & 0x80000000) break;
    }
    if ((afterShift & 0x01ff)>0x0100)
        flag=1;//在截断数值部分低位的时候有两种情况要进行进位 第一种后面九位最高位为1 剩余八位不为0
    else if ((afterShift & 0x03ff)==0x0300)
        flag=1;//第二种最后九位为100000000 截断前一位也为1
    else
        flag=0;

    return sign + (afterShift>>9) + ((159-shiftLeft)<<23) + flag;
}

15.float_twice

/* 
 * float_twice - 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 float_twice(unsigned uf) {
   unsigned f = uf;
    if ((f & 0x7F800000) == 0) //
    {
        //如果exp位全为0 符号位不变 左移
        f = ((f & 0x007FFFFF) << 1) | (0x80000000 & f);
    }

    else if ((f & 0x7F800000) != 0x7F800000)
    {//如果exp不全为1 exp部分加一
        f =f + 0x00800000;
    }
    return f;//其余情况 无穷以及Nan直接返回本身
}
01·容错脚本 BY 轮回者 本脚本基于星大叔的容错脚本第2版,建立两个txt文件(log_bitmap.txt log_audio.txt),对系统缺失的文件进行补救,也就是缺失文件照样可以玩游戏。 02·角色加入提示(开关2) 角色加入、离开提示。 03·分开距离自动跟随(开关4) 传说中的“开火车”。 04·加强窗口(选项动态加强)作者:carol3 05·读书读报系统(开关50) by 柳柳 参考注释打开开关,则进入读书系统,系统会连续不停地读取“显示文章”的内容显示在一个窗口中,直到碰到其他事件。 06·天气系统 by ScriptKitty and Mr.DJ 共包含16个天气,(具体看脚本里的长篇说明)。 07·按键加速 08·光标循环移动 菜单可以循环选择 09·升级加点系统 本脚本不会取代默认的升级,但可以用这个功能手动追加点数。 如果你想纯粹使用手动加点(而升级不提升能力),只要把数据库中角色升级能力,1-99级全部等于一个相同数值就行了(具体看脚本里的长篇说明)。 10·升级提示 (开关5) By 叶子 原作者:桜雅 在土 11·防卡机 作者:“用我的视野范围去限制刷新的事件,因此一个有300多个事件的大地图仍然可以运行在40的帧速率。这可能不是最后一个版本,我还在考虑更多的方法减少事件的拖慢” 12·半透明菜单 13·截图 14·按键调用 By: Cybersa 15·文字投影效果 16·全屏幕(API) 17·游戏版权(游戏开始时显示LOGO) 18·杀敌随机金钱 by.我要食叉包 19·商店显示 优化了商店 20·价格变动 翻译:柳柳 21·菜单显示血条 22·物品分类 可以自定义设置物品分类,利用物品描述,每个描述后面添加@物品分类即可。 23·任务和菜单 by 柳柳 24·完美输入法(具体看脚本里的长篇说明) 25·显示敌人生命百分比 作者:carol3_柳柳 26·显示地图名 by 桜雅 在土 27·截图存取档(具体看脚本里的长篇说明) 28·真实商店(具体看脚本里的长篇说明) 29·即时消息脚本(仿网游,甚者可以外接成为聊天框) 30·贵重物品特殊颜色 31·等级突破 32·显示每个事件的名字 作者:柳柳 加强:叶子 33·事件的储存读取进度 34·偷盗系统 By 绿发的Eclair 35·完整鼠标系统 By whbm 36·繁体字 (把简体字转换为繁体字?) 37·直接用地图做战斗背景 脚本作者:bluefool 38·显示ARPG by 刻宮 39·fuki v6 (具体看脚本里的长篇说明) 40·得失提示 作者:KKME,联系QQ:6690474 41·套装系统 By 凌冰 42·价格变动 by 和希成纳 、桜雅在土 43·坐标显示 44·四方向寻路 By whbm 45·防卡机2 (应该是放挂机才对) 46·小地图 by ピニョン clum-sea 游戏中,按下shift键可以开关地图, 47·更新加密游戏(暂时用不着)(具体看脚本里的长篇说明) 48·银行系统(开关12)(具体看脚本里的长篇说明) 49·魔物图鉴(具体看脚本里的长篇说明) 50·自动更新(暂无效)BY 亿万星辰(具体看脚本里的长篇说明) ---2.01测试---- 1.RM计算机by 七夕小雨 2.解决RM的10s 3.打造 4.鼠标脚本控制窗口滚动 5.光标位置记录 6.移动的公告 by bbaugle 7.特技升级 by Claimh 8.彩虹神剑 by 柳柳 修改 by 叶子 9.远景自动移动 by ぷのくー 10.全键盘检测 11.多重状态 by Claimh 12.技能连击追加 by Claimh 13.显示敌人列表 Scene_Battle 14.回合表示 15.转到输入下一个角色的命令 16.魔法商店 17.视角跟随NPC 18.颜色随血量变化 19.组合键连续特技系统 By 绿发的Eclair 20.游戏版权LOGO(结束游戏时)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值