csapp_lab01

一、 环境搭建

wget https://gitee.com/lin-xi-269/csapplab/raw/origin/installAll.sh # 下载脚本
bash installAll.sh # 运行脚本

二、题目

这个实验需要做的就是实现bits.c中的函数:

make btest
# 测试
./btest

2.1 bitXor

实现xor(^)操作,之能够使用not(~)and(&),这里主要需要使用逻辑代数里面的基本运算规则,首先推导出xor的基本表达式:

在这里插入图片描述
由上图可知,xor的基本表达式为 x ‾ ⋅ y + x ⋅ y ‾ \overline{x}\cdot{y} + x\cdot{\overline{y}} xy+xy,这里面存在+,题目要求是不可以存在+,这里需要通过反演律来消除+
x ‾ ⋅ y + x ⋅ y ‾ = x ‾ ⋅ y + x ⋅ y ‾ ‾ ‾ = x ‾ ⋅ y ‾ ⋅ x ⋅ y ‾ ‾ ‾ = ( x + y ‾ ) ⋅ ( x ‾ + y ) ‾ = x ‾ ⋅ y ‾ + x ⋅ y ‾ = x ‾ ⋅ y ‾ ‾ ⋅ x ⋅ y ‾ \begin{equation} \begin{split} \overline{x}\cdot{y} + x\cdot{\overline{y}} &= \overline{\overline{\overline{x}\cdot{y} + x\cdot{\overline{y}}}} \\ &= \overline{\overline{\overline{x}\cdot{y}} \cdot \overline{x\cdot{\overline{y}}}} \\ &= \overline{(x+\overline{y}) \cdot (\overline{x}+y)} \\ &= \overline{\overline{x}\cdot \overline{y} +x\cdot y} \\ &= \overline{\overline{x}\cdot \overline{y}} \cdot \overline{x\cdot y} \end{split} \end{equation} xy+xy=xy+xy=xyxy=(x+y)(x+y)=xy+xy=xyxy

/* 
 * bitXor - x^y using only ~ and & 
 *   Example: bitXor(4, 5) = 1
 *   Legal ops: ~ &
 *   Max ops: 14
 *   Rating: 1
 */
int bitXor(int x, int y) {
  int a = ~((~x)&(~y));
  int b = ~(x&y);
  return a&b;
}

2.2 tmin

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

2.3 isTmax

判断x是否为整形的最大数:

/*
 * 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 res = !(x^((1<<31)-1));
  return res;
}

2.4 allOddBits

判断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) {
  return !((0xAAAAAAAA&x)^0xAAAAAAAA);
}

2.5 negate

返回x的负数

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

2.6 isAsciiDigit

判断x是否位于 0x30 <= x <= 0x39,也就是说满足x-0x30>=0以及0x39-x>=0,也就是说表达式结果的最高位为0,因为满足条件取1,所以需要将0转化为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 bool1 =  !((x-0x30)>>31);
  int bool2 = !((0x39-x)>>31);
  return bool1 & bool2;
}

2.7 conditional

如果x!=0返回yx==1返回z!!x可以将x转化为0或者1, 然后通过移位操作转化为000...或者1111...

/* 
 * 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) {
  int mask = (!!x)<<31;
  return (mask&y) | ((~mask)&z);
}

2.8 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) {
// 这里只需要枚举出所有正确的情况
  int cond1 = !(x^y);
  int signX = (x>>31)&0x1;
  int signY = (y>>31)&0x1;

  int cond2 = (!(signX^signY)) & ((x+(~y)+1) >> 31);

  int cond3 = signX&(!signY);

  return cond1 | cond2 | cond3 ;
}

2.9 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) {
  // 0的补码还是0 0^regX(0) = 0 
  // 非0的补码最高bit不同
  // 1=>0, 0=>1
  int res1 = (x>>31)&0x1;
  int res2 = ((~x+1)>>31)&0x1;
  return (res1 | res2) ^ (0x1);
}

2.10 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) {
  // 不管x是正还是负数都需要把高处的非必要转化为0
  int mask = x >> 31;
  // 这里需要对于正负数进行带入
  x = x&(~mask) | x^mask;
  // 0000 0000 0000 0000 |0000 0000 1111 1111
  // !!(x>>16) 判断高16为
  int b16 = (!!(x>>16))<<4;
  // 成功移动, 不论"!!(x>>16)"为0还是1, 将来需要进行判定的有效位都在[0:15]区间
  x = x>>b16;
  
  int b8 = (!!(x>>8))<<3;
  x = x>>b8;

  int b4 = (!!(x>>4))<<2;
  x = x>>b4;
  
  // 符号位被消解
  int b2 = (!!(x>>2))<<1;
  x = x>>b2;

  // 剩下2个
  int b1 = (!!(x>>1))<<0;
  x = x>>b1;

  int b0 = !(x^0x1);
  // b0~b16不会全部为1,体会一下
  return 1 + b0 +b1 + b2 + b4 + b8 + b16;
}

2.11 floatScale2

//float
/* 
 * 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) {
  // f*2
  int sign = !!(uf>>31);
  int expr = ((uf>>23)&0xFF);
  int frac = uf&0x7FFFFF;

  // NaN
  if (expr==0xFF && frac != 0) return uf;

  // 无穷达
  if (expr==0xFF && frac == 0) return uf;

  if (expr==0) { // 非常小的float
    return (sign<<31) | (frac << 1);
  }

  // 正常float, 指数+1表示*2
  expr++;

  return (sign<<31) | (expr<<23) | frac ;
}

2.12 floatFloat2Int

int floatFloat2Int(unsigned uf) {
  // 浮点数转化为整型
  int sign = !!(uf>>31);
  int expr = ((uf>>23)&0xFF);
  int frac = uf&0x7FFFFF;

  if (expr==0xFF) return 1<<31;

  if (expr==0) return 0;  // 很小的float

  int E = expr-127;
  // 释放出隐藏的1
  int frac_ = (1<<23) | frac;
  // res表示的是原码
  int res = 0;
  // 相当于对于frac进行左或者右移
  if (E<0){
    return 0;
  } else if (E<23){
    res = frac_>>(23-E);
  } else if (E<31) {
    res = frac_<< (E-23);
  } else {
    return 1<<31;
  }

  // 负数的话需要转化为补码
  if (sign) res = (~res)+1;

  return res;
}

2.13 floatPower2

/* 
 * 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
 */
  # if 0 
  极小:
    expr=0; E=0-127=-127; frac_min = 2-23, 2-1 , [-149, -127] 
    最大2-127 会导致不连续
  正常:
    expr=1; E=1-127 = -126(可以获取到)  最小2^-126
    expr = 254; E= 254-127 = 127; 2^127 * 1.1111... < 2^128 [-126, 127]
  #endif
unsigned floatPower2(int x) {
  // 太小的话返回0 
  // 太大的话返回+INF
  // 1. 需要确定float 可以表示的边界值在哪里
  // expr=0, E=0-127 = -127, -23 (下限)
  if (x<-149) { // 无法表示
    return 0;
  } else if(x<=-127){ // 非规格化 expr = 0; E = -126;
    int shift = x+149;
    return 1<<shift;
  } else if (x<=127){ // 规格化, frac=1.0 // x = expr -127 => expr = x+127 
    int expr = x+127;
    return  expr << 23;
  }else{
    return 0xFF<<23;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值