CSAPP Lab1--Manipulating Bits

实验材料:http://download.csdn.net/detail/u010560443/9458964

/*
 * bitNor - ~(x|y) using only ~ and &
 *   Example: bitNor(0x6, 0x5) = 0xFFFFFFF8
 *   Legal ops: ~ &
 *   Max ops: 8
 *   Rating: 1
 */
int bitNor(int x, int y) {
  return (~x)&(~y);
}

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

    return (~(x&y)&~(~x&~y));

}
/*
 * isNotEqual - return 0 if x == y, and 1 otherwise
 *   Examples: isNotEqual(5,5) = 0, isNotEqual(4,5) = 1
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 6
 *   Rating: 2
 */
int isNotEqual(int x, int y) {

    return (!!(x ^ y));
}
/*
 * 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;
}
/*
 * copyLSB - set all bits of result to least significant bit of x
 *   Example: copyLSB(5) = 0xFFFFFFFF, copyLSB(6) = 0x00000000
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 5
 *   Rating: 2
 */
int copyLSB(int x) {
    return x<<31>>31;
}
/*
 * logicalShift - shift x to the right by n, using a logical shift
 *   Can assume that 1 <= n <= 31
 *   Examples: logicalShift(0x87654321,4) = 0x08765432
 *   Legal ops: ~ & ^ | + << >>
 *   Max ops: 16
 *   Rating: 3
 */
int logicalShift(int x, int n) {
    return (x>>n)&(~((1<<31)>>n<<1));
}
/*
 * bitCount - returns count of number of 1's in word
 *   Examples: bitCount(5) = 2, bitCount(7) = 3
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 40
 *   Rating: 4
 */
int bitCount(int x) {

    //for every 4 bits, save the number of 1's into itself .
    //max number is 4 ,can be saved
    int mask,sum;

    mask=0x11|(0x11<<8);
    mask=mask|(mask<<16);
    sum=x&mask;

    sum+=(x>>1)&mask;
    sum+=(x>>2)&mask;
    sum+=(x>>3)&mask;

    //add high 16 bits into low 16 bits
    //max number is 8,can be saved by 4 bits
    mask=0xff|(0xff<<8);
    sum=(sum>>16)+(sum&mask);

    //for every 8 bits in low 16 bits,add high 4 bits into low 4 bits
    //max number is 16 ,can't be saved .so let it saved by 8 bits
    mask=0xf|(0xf<<8);
    sum=((sum>>4)&mask)+(sum&mask);

    //add high 8 bits into low 8 bits,
    mask=0xff;
    sum=(sum&mask)+(sum>>8);
    return sum;
}
/*
 * bang - Compute !x without using !
 *   Examples: bang(3) = 0, bang(0) = 1
 *   Legal ops: ~ & ^ | + << >>
 *   Max ops: 12
 *   Rating: 4
 */
int bang(int x) {
    //notice the sign bit of +0 and -0 are both 0 ,but others are not.
    int negx=~x+1;
    int x_sign=(x>>31)&0x1;
    int negx_sign=(negx>>31)&0x1;

    return (x_sign|negx_sign)^0x1;
}
/*
 * leastBitPos - return a mask that marks the position of the
 *               least significant 1 bit. If x == 0, return 0
 *   Example: leastBitPos(96) = 0x20
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 6
 *   Rating: 4
 */
int leastBitPos(int x) {
    //x and -x have the same least significant bit
    return x&(~x+1);
}
/*
 * TMax - return maximum two's complement integer
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 4
 *   Rating: 1
 */
int tmax(void) {
    return (1<<31>>31)^(1<<31);
}
/*
 * isNonNegative - return 1 if x >= 0, return 0 otherwise
 *   Example: isNonNegative(-1) = 0.  isNonNegative(0) = 1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 6
 *   Rating: 3
 */
int isNonNegative(int x) {
    return ((x>>31)&0x1)^0x1;
}
/*
 * isGreater - if x > y  then return 1, else return 0
 *   Example: isGreater(4,5) = 0, isGreater(5,4) = 1
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 24
 *   Rating: 3
 */
int isGreater(int x, int y) {
    //positive:0  , negtive: -1
    int sign_x=x>>31;
    int sign_y=y>>31;

    //when sign is equal
    int equal=(!(sign_x^sign_y))&((~y+x)>>31);
    //when sign is not equal
    int notEqual=sign_x&!sign_y;
    return !(equal|notEqual);
}
/*
 * 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) {
    //mask = (2^n)-1
    int mask = (1 << n) + ~0;
    //positive: equalizer=0 ; negtive:  equalizer=(2^n)-1
    int equalizer = (x >> 31) & mask;
    //negtive need add (2^n)-1
    return (x+equalizer)>>n;
}
/*
 * abs - absolute value of x (except returns TMin for TMin)
 *   Example: abs(-1) = 1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 10
 *   Rating: 4
 */
int abs(int x) {
    //positive:0  , negtive: -1
    int mask=x>>31;
    //if x<0,res=~x ;else if x>=0, res=x;
    int res=mask^x;
    if x<0,addition=1 ;else if x>=0, res=0;
    int addition=(x>>31)&0x1;

    return res+addition;
}
/*
 * addOK - Determine if can compute x+y without overflow
 *   Example: addOK(0x80000000,0x80000000) = 0,
 *            addOK(0x80000000,0x70000000) = 1,
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 20
 *   Rating: 3
 */
int addOK(int x, int y) {
    //calulate the sign of x,y and sum
    int sum=x+y;
    int signx=(x>>31)&0x1;
    int signy=(y>>31)&0x1;
    int signsum=(sum>>31)&0x1;

    //overflow when signx=0 and signy=0 but signsum=1 ,
    //overflow when signx=1 and signy=1 but signsum=0
    int result=!!((signx^signy)+!(signx^signsum)+!(signy^signsum));
    return result;
}

你可能感兴趣的:(实验,csapp)