csapp-lab1

1、bitXor

/*
 1* 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));
}

2.tmin

 * tmin - return minimum two's complement integer 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 4
 *   Rating: 1
 */

思路: 最小值为1000 0000 0000 0000 0000 0000 0000 0000,所以我们可以让1 << 31位。

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

 3.isTmax


/*
 * isTmax - returns 1 if x is the maximum, two's complement number,
 *     and 0 otherwise 
 *   Legal ops: ! ~ & ^ | +
 *   Max ops: 10
 *   Rating: 1
 */

思路:

最大值 0111 ... 1111,假设a = maximum, 那 a + 1 = 1000 ... 0000,取反之后就等于a,可以做个&运算,如果相等就返回1,不相等就返回0。但是也有个特例,假设a = 1111 .... 1111, a + 1 = 0000 .... 0000。那再做&运算也是返回1, 所以我们还得加个条件: a + 1 = 0,那我们规格化一下 !!(a + 1)还是 0,然后和 !!(a + 1) ^ 0x0),因为不是maximum就返回0,他如果和0一样正好返回0,和要求一样。

int isTmax(int x){
    return (!((~(x + 1)) ^ x)) & (!!(x + 1) ^ 0x0));

4. allOddBits

/* 
 * 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 2;

意思就是奇数为1,则返回1,否则返回0

思路:

四位 1010 满足奇数为1,所以 定义 int A = 0xA。然后左移四位,

int AA = A << 4 = 1010 0000。然后让 A | AA = 0000 1010 | 1010 0000 = 1010 1010 

依此类推 ,定义 AAA (左移8位) AAAA(左移16);然后  !((x & AAAA) ^ AAAA),因为如果满足条件,(x & AAAA) ^ AAAA = 0 ,!((x & AAAA) ^ AAAA) = 1,不满足就为0.

int allOddBits(int x) {
    // 4位 1010 = 0xA
    int A = 0xA;
    // 8位
    int AA = A | (A << 4);    
    // 16位
    int AAA = AA | (AA << 8);
    // 32位
    int AAAA = AAA | (AAA << 16);

    return !((x & AAAA) ^ AAAA);
}

5.negate


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

这个就是~x + 1

int negate(int x) {
  return ~x + 1;
}

6.isAsciiDigit

/* 
 * 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) {
  return 2;
}

思路:

1、满足条件是在0x30 - 0x39 也就是 11 0000 -- 111001,我们右移六位看看之后的结果是否为0,为0则满足。

2、满足条件是在0x30 - 0x39 也就是 11 0000 -- 111001,所以我们右移四位看看是否满足最后两位是11,也就是右移之后与0b11做异或。

3、因为0x30 - 0x39 我们可以让q =  x 和 0xf 与运算,然后看看最后四位是否满足在 0000 - 1001,可以让 res = q - 0xA,如果 res 小于 0 就满足,否则不满足,

可以让cond3 = res >> 31位。!!cond3 为 1就说明满足,为0就说明不满足。

int isAsciiDigit(int x) {undefined

    //1、满足条件是 0011 0000 --- 0011 1001
    //右移6位看看右移之后的结果是否为0,
    int cond1 = !(x >> 6);

    //2、因为满足的是11 0000 --- 11 1001
    可以右移四位看看最后两位是否是11
    int z = x >> 4;
    int cond2 = !(z ^ 0b11);

    //3、最后四位范围是在 0000 --- 1001 A是正好超过 
    //可以让x & 0xf,保存最后四位的结果。
    int q = x & 0xf;
    //然后让q - 0xA 看是否小于0, 直接查看他的符号位
    int res = q - 0xA;
    int cond3 = !!(res >> 31);

    return cond1 & cond2 & cond3;
}

7.conditional

/* 
 * 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) {
  return 2;

意思就是if(x),x是非0,就返回y,如果是0就返回z。


int conditional(int x, int y, int z) {
    //非0数的话c = 1, 0的话 c = 0
    int c = !!x;
    //如果是非0  c 最后会变成0xf
    c = ~c + 1;
    //如果满足就返回y,否则返回z
    return (y & c) | (~c & z);
    //因为如果非0 c = 0xf,那么y & c就还是y,就可以返回y
    //如果是0 c = 0x0,那么y & c就是0, 就看z ~c = 1111 就会返回z
}

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) {
  return 2;
}

思路:就是让你判断 x - y <= 0 是否成立。

这里面会有四种情况:

  1. x == y

我们可以让x 和 y做异或 ,因为如果两个相等就会返回0,那我们可以!(x ^ y)就会返回1.

  1. x + y -

如果x是正的,y是负的,那么x - y > 0 了,就不满足条件。所以我们可以右移31位,记录一下符号位。因为x 是正的,就会等于0, y是负的,就会等于1。定义signX 为x的符号位,signY为y的符号位。所以定义cond2 = !(signY & (!signX))。因为 !signX为1,                  signY & (!signX) =1,所以!(signY & (!signX)) = 0。所以正好返回0

  1. x - y +

和上面一样,x是负的,y是正的。所以signX为1, signY为0。这个是满足条件的,所以返回1,所以定义cond2 = ((!signY) & signX)。因为 !signY为1 ,((!signY) & signX) =1。所以正好返回1

  1. x - y - || x + y +

因为正负都一样所以signX为1, signY为1,或者signX为0, signY为0。这个是满足条件的的话,x - y < 0,所以我们定义一个res = (x + (~y) + 1) >> 31,这样我们可以得到他的符号位,如果这个符号位为1,说明满足,如果为0,就是不满足。所以我们res2 = res & 0x1,res2 == 1就是满足,返回1,不满足,返回0。

int isLessOrEqual(int x, int y){
    // x - y <= 0
    //1、x == y
    int cond1 = !(x ^ y);

    //2、x + y - 不满足
    int signX = x >> 31;// signX = 0
    int signY = y >> 31;// signY = 1
    int cond2 = !((~signX) & signY);// cond2 = 0

    //3、x - y + 满足
    //signX = 1, signY = 0
    int cond3 = (signX & (~signY));//cond3 = 1

    //4、x + y + || x - y - 
    //当x - y < 0 就说明返回1 否则返回0
    //x - y == x + (~y) + 1
    int res = (x + (~y) + 1) >> 31;//满足为1, 不满足为0
    int res2 = (res & 0x1);//如果为1 说明满足,0为不满足

    return cond1 ||(cond2 && (cond3 || res2));
}

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) {
  return 2;
}

如果x是非0,那说明~x + 1 也不是非0,(x & ((~x) + 1)) >> 31 = 1,如果是0,就会得到0.

int logicalNeg(int x) {
    int negX = (~x) + 1;
    int sinal = (x & negX) >> 31;//signal = 1说明非0,signal = 0,说明为0
    return signal + 1;
}

10.howManyBits

 
正数  12 = 0000 1100 其中高位1 是第四位,但是还有一个是符号位,所以加上符号位就是5

0 就默认是1 

负数 -13 = 1111 0011, 10011 = -13 这说明我们只需要找到符号位之后第一个0

int howManyBits(int x) {                                             
        int iszero = !x;
	int flag = x >> 31;
	int mask = ((!!x) << 31) >> 31;
	x = (flag & (~x)) | ((~flag) & x); 
	int bit_16, bit_8, bit_4, bit_2, bit_1, bit_0;

    //如果你的前 16 位有1, 那么说明至少需要16位,
    //有1 (!((!!(x >> 16)) ^ 0x1)) = 0x1 
    //左移4位正好等于16                                              
    bit_16 = (!((!!(x >> 16)) ^ 0x1)) << 4; 
	x >>= bit_16;   

	bit_8 = (!((!!(x >> 8)) ^ 0x1)) << 3; 
	x >>= bit_8; 

	bit_4 = (!((!!(x >> 4)) ^ 0x1)) << 2; 
	x >>= bit_4; 

	bit_2 = (!((!!(x >> 2)) ^ 0x1)) << 1; 
	x >>= bit_2; 

	bit_1 = (!((!!(x >> 1)) ^ 0x1)); 
	x >>= bit_1; 

	bit_0 = x;

	int res = bit_16 + bit_8 + bit_4 + bit_2 + bit_1 + bit_0 + 1;

	return iszero | (mask & res);
	                                           
}

11. floatScale2

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

题目的意思就是让我们算2 * f

首先需要记住浮点数的表示方式

 浮点数的表达方式:

v = (-1)^s * M * 2 ^ E

所以我们需要知道这个数的s,expr,frac

1、首先是s 也就是符号为

2、E = expr - bias 单精度biass 127,双精度是1023,所以我们要知道这个expr

因为分成四种情况:规格化、非规格化、无穷大、NaN

2.1规格化:x >> 23位然后 x & 0xff ,得到expr,因为我们是要把x * 2,其实也就是让expr加一就可以,所以对应的就是expr ++;

2.2非规格化:x & 0x7fffff 得到frac,其实就是frac << 1

2.3如果为0,那还是0

2.4 无穷大,那还是无穷大

int floatScale2(unsigned uf){
    unsigned s = (uf >> 31) & 0x1;
    unsigned expr = (uf >> 23) & 0xff;
    unsigned frac = uf & 0x7fffff;

    //0
    if(expr == 0 && frac == 0){
        return uf;
    }

    //非规格化
    if(expr == 0){
        //E = 1- 127
        frac <<= 1;
        return (s << 31) | frac;
    }
    

    //无穷大
    if(expr == 0xff){
        return uf;
    }


    //规格化
    expr ++;
    return (s << 31) | (expr << 23) | (frac);
}

12.floatFloat2Int

 * 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 s = (uf >> 31) & (0x1);
    unsigned expr = (uf >> 23) & (0xff);
    unsigned frac = (uf & 0x7fffff);

    if(expr == 0 && frac == 0){
        return 0;
    }

    if(expr == 0xff){
        return 1 << 31;
    }


    if(expr == 0){
        return 0;
    }


    int E = expr - 127;
    frac = frac | (1 << 23);

    if(E > 31){
        return 1 << 31;
    }

    else if(E < 0){
        return 0;
    }

    if(E >= 23){
        frac <<= (E -23);
    }
    else{
        frac >>= (23 - E);
    }

    if(s)
        return ~frac + 1;
    return frac;
    

13.floatPower2

 再学学。。。

unsigned f1oatPower2(int x){
    if(x < -149){
        return 0;
    }else if(x < -126){
        int shift = 23.+(x+ 126);
        return 1 << shift;
    }else if(x <= 127){
        int expr = x + 127;
        return expr << 23;
    }else {
        return (0xff)<< 23;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值