其他分享
首页 > 其他分享> > 深入理解计算机原理(csapp第三版)——datalab

深入理解计算机原理(csapp第三版)——datalab

作者:互联网

代码:https://gitee.com/iwehdio/csapp-lab

1. bitXor

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 res = ~(~(x & ~y) & ~(~x & y));
    return res;
}
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

int tmin(void) {
    int res = 1 << 31;
    return res;
}

3. isTmax

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 addOne = x + 1;
    int res = addOne ^ ~x;
    return !(res + !addOne);
}

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) {
    int mask = 0xAA;
    mask |= mask << 8;
    mask |= mask << 16;
    int res = (x & mask) ^ mask;
    return !res;
}

5. negate

negate - return -x

Example: negate(1) = -1.

Legal ops: ! ~ & ^ | + << >>

Max ops: 5

Rating: 2

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

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) {
    int highBit = !((x >> 4) ^ 0x3);
    int bitOne = (x>>3) & 0x1;
    int bit23 = (x>>1) & 0x3;
    return highBit & (!bitOne | !bit23);
}
int isAsciiDigit(int x) {
  int sign = 0x1<<31;
  int upperBound = ~(sign|0x39);
  int lowerBound = ~0x30;
  upperBound = sign&(upperBound+x)>>31;
  lowerBound = sign&(lowerBound+1+x)>>31;
  return !(upperBound|lowerBound);
}

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) {
    int flag = ~!!x + 1;
    return (flag & y) | (~flag & 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) {
    int diff = ~x + y + 1;
    int signX = (x>>31) & 0x1;
    int signY = (y>>31) & 0x1;
    int signD = (diff>>31) & 0x1;
    int sameSign = !(signX ^ signY);
    return (sameSign & !signD) | (!sameSign & signX);
}

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) {
    int com = ~x + 1;
    int signOrigin = (x>>31) & 0x1;
    int signCom = (com>>31) & 0x1;
    int sameSign = signOrigin ^ signCom ^ 0x1;
    return sameSign & (((x>>31) & 0x1) ^ 0x1);
}
int logicalNeg(int x) {
  return ((x|(~x+1))>>31)+1;
}

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) {
    int sign = x>>31;
    int y = (sign & ~x) | (~sign & x);
    int b16 = (!!(y>>16))<<4;     //高十六位是否有1
    y = y>>b16;                   //如果有(至少需要16位),则将原数右移16位
    int b8 = (!!(y>>8))<<3;       //剩余位高8位是否有1
    y = y>>b8;                    //如果有,则右移8位
    int b4 = (!!(y>>4))<<2;
    y = y>>b4;
    int b2 = (!!(y>>2))<<1;
    y = y>>b2;
    int b1 = !!(y>>1);
    y = y>>b1;
    int b0 = y;
    return b16 + b8 + b4 + b2 + b1 + b0 + 1;
}

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) {
    unsigned sign = uf >> 31;
    unsigned exp = (uf >> 23) & 0xFF;
    unsigned frac = uf & 0x7FFFFF;
    if(exp==0xFF) {
        return uf;
    } else if(exp!=0) {
        exp += 1;
    } else {
        if((frac>>22)&0x1) {
            frac = frac & ~0x800000;
            exp = 1;
        }
        frac = frac<<1;
    }

    return (sign<<31) | (exp<<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 f) {
    unsigned sign = f >> 31;
    unsigned exp = (f >> 23) & 0xFF;
    unsigned frac = f & 0x7FFFFF;
    unsigned e, half, round, rest;
    int k = 23;
    int bias = 127;
    if(exp==0xFF) {
        return 0x80000000;
    }
    if(exp < bias) {   //(1<<(8-1))-1
        return 0;
    } else {
        frac |= 0x800000;
        e = exp - bias;
        if(e<k) {
            half = 1<<(k - e - 1);
            round = frac & ((1<<(k - e)) - 1);
            rest = frac >> (k - e);
            if(round>half) {
                rest += 1;
            } else {
                if(round==half && (rest & 0x1)) {
                    rest += 1;
                }
            }
        } else if(e<31) {
            rest = frac << (e - k);
        } else {
            return 0x80000000;
        }
    }
    if(sign) {
        rest = ~rest + 1;
    }
    return rest;
}

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

unsigned floatPower2(int x) {
    int k = 23;
    int bias = 127;
    unsigned frac;
    unsigned exp;
    if(x>bias) {
        return 0x7F800000;
    } else if(x>=-bias) {
        exp = x + bias;
        frac = 0;
    } else if(x>=-bias-k+2) {
        exp = 0;
        frac = 1<<(bias+k-2+x);
    } else {
        return 0x0;
    }
    return (exp<<k) | frac;
}

标签:csapp,return,ops,int,31,第三版,datalab,Legal,unsigned
来源: https://www.cnblogs.com/iwehdio/p/15679889.html