在复旦读研,进来就先让我做几个lab int bitOr(int x, int y) { /*because & with ~ is |(or operation), I represent |(or operation) like below*/ int result = ~(~x&~y); //It will be x|y return result; //return result value } /* * 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) { /* to judge x<=y, i use Karnaugh Map with signbit. x y z=(y-x) result 0 0 0 1 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 1 1 0 1 1 1 1 0 1 1 1 1 0 it is shortly represented by ~y~z + ~yx + ~zx -> (~y&~z) | (~y&x) | (x&~z)*/ int y_minus_x=y+(~x+1); /*temporally, the (y-x) value is saved to variable*/ int result=(((~y&~y_minus_x)|(~y&x)|(x&~y_minus_x))>>31)&1; /*insert x and y to Boolean algebra that was made by me. next, extract signbit using right shift and 'and' operation.*/ return result; // return result value } /* * isZero - returns 1 if x == 0, and 0 otherwise * Examples: isZero(5) = 0, isZero(0) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 2 * Rating: 1 */ int isZero(int x) { /*I use notion that 0 is always 0 with 'or' operation with 0, otherwise, 1 First, execute x with 'or' operation with 0x0. Second, execute '!' operation. Therefore, it's output is 0 in case of x is 0, otherwise 1.*/ int result = !(x|0x0); //conclude x is 0 or other value. return result; //return result value } /* * log2 - return floor(log base 2 of x), where x > 0 * Example: log2(16) = 4 * Legal ops: ! ~ & ^ | + << >> * Max ops: 90 * Rating: 4 */ int log2(int x) { /* When i write x value and calculate log2's value for binary code by hand, I recognize that the result value is determined by first coming out of 1 from the left. Therefore, first, make first coming out of 1's all right to be 1 and count the number of 1. When count 1's number, i use bit count practice*/ int tool=0x11; //variable for count 1's number int tmpresult=0; //variable to save temporal value int result=0; // variable to return final value x=x>>1; //because of log2's definition, shift to right once. x=(x>>1)|x; //to make first 1 of right is all to be 1 x=(x>>2)|x; //to make first 1 of right is all to be 1 x=(x>>4)|x; //to make first 1 of right is all to be 1 x=(x>>8)|x; //to make first 1 of right is all to be 1 x=(x>>16)|x; //to make first 1 of right is all to be 1 tool=tool^(tool<<8); //using shift, to make 0x11111111 tool=tool^(tool<<16); //using shift, to make 0x11111111 tmpresult=x&tool; //count 1's number ex) 0001 tmpresult+=((x>>1)&tool); //count 1's number ex) 0010 tmpresult+=((x>>2)&tool); //count 1's number ex) 0100 tmpresult+=((x>>3)&tool); //count 1's number ex) 1000 tmpresult=(tmpresult>>16)+tmpresult; //fold as half and add to concentrate to right space //ex) 0x'12121212' to 0x1212'2424' result=(tmpresult&0xf); //extract 1's number and save to result variable //ex) 0x00000003 result+=((tmpresult>>4)&0xf); //extract 1's number and save to result variable //ex) 0x00000030 result+=((tmpresult>>8)&0xf); //extract 1's number and save to result variable //ex) 0x00000300 result+=((tmpresult>>12)&0xf); //extract 1's number and save to result variable //ex) 0x00003000 return result; //return result value } /* * 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) { /*It is almost same as 'iszero' practice. 0 is always 0 (it is signbit) with 'and' operation , whenever 0 value is value of original or of 2's complement. First, execute 'and' operation with value of 1's complement of x and value of 1's complement of negative x. Second extract signbit by right shift and 'and' with 0x1. therefore, it's output is 1 in case of x is 0, otherwise 0.*/ int result = (((~x)&(~(~x+1)))>>31)&0x1; //execute line explained above. return result; //return result value } /* * multFiveEights - multiplies by 5/8 rounding toward 0. * Examples: multFiveEights(77) = 48 * multFiveEights(-22) = -13 * You can assume |x| < (1 << 29) * Legal ops: ! ~ & ^ | + << >> * Max ops: 12 * Rating: 3 */ int multFiveEights(int x) { /*First, just execute x * 5/8. Second, to be rounded toward 0, when variable of temp's signbit is 1, it add to result value(case of what signbit is 0 is also add 0) Because when positive value is multiplied with 5/8, its value is correct but when negative value is multied with 5/8, its value lacks 1*/ int temp=(((x<<2)+x)>>3); //execute multiply 5/8 int result=temp+(((temp>>31)&0x1)); /*for the explained reason, extract signbit and add to result*/ return result; //return result value } /* * satAdd - adds two numbers but when positive overflow occurs, returns * maximum possible value, and when negative overflow occurs, * it returns minimum positive value. * Examples: satAdd(0x40000000,0x40000000) = 0x7fffffff * satAdd(0x80000000,0xffffffff) = 0x80000000 * Legal ops: ! ~ & ^ | + << >> * Max ops: 30 * Rating: 4 */ int satAdd(int x, int y) { /*When x+y is not occured overflow, the result value is x+y. When positive overflow, the result value is 0x7fffffff. When negative overflow, the result value is 0x80000000. To solve this practive, make two Boolean algebra using Karnaugh map. First formula is to make x's value to be 0x7fffffff when overflow. Second formula is to add to result value to be 0x80000000 when negative overflow*/ int z=x+y; //add x+y int check_over=(((~x)&(~y)&z)|(x&y&(~z))); //is made by Karnough map int p_over=(check_over>>31)<<31; // it is used when overflow, // to make value 0x7fffffff int n_over=~(~x&~y&z&check_over)>>31; /*it is used when negative overflow, to add 1 to result value it is made by Karnaugh map.*/ int result=(z|check_over>>31)+((check_over>>31)&0x1)+~p_over+(~n_over+1); //it is final formula explained above notation return result; //return result } /* * tc2sm - Convert from two's complement to sign-magnitude * where the MSB is the sign bit * You can assume that x > TMin * Example: tc2sm(-5) = 0x80000005. * Legal ops: ! ~ & ^ | + << >> * Max ops: 15 * Rating: 4 */ int tc2sm(int x) { /*I use two step. First, make x to absolute value. Second, add signbit to result value. Therefore, sign-magnitude value is completed!!*/ int abs_x=(x+(x>>31))^(x>>31); /*abs_x is absolute value. when positive value, return original value. when negative value, execute 2's complement.*/ int signbit=(x>>31)<<31; //extract signbit int result=signbit|abs_x; //change msb to signbit of x return result; //return result value } /* * bitMask - Generate a mask consisting of all 1's * lowbit and highbit * Examples: bitMask(5,3) = 0x38 * Assume 0 <= lowbit <= 31, and 0 <= highbit <= 31 * If lowbit > highbit, then mask should be all 0's * Legal ops: ! ~ & ^ | + << >> * Max ops: 16 * Rating: 3 */ int bitMask(int highbit, int lowbit) { /*To generate bitmask with highbit and low, first, make 1's complement of 0x0 and use shift. (I intend ~0x0<(highbit+1) but it generate irregural result. so, shift left by highbit and one more time.) Second, execute 'xor' operation with maskhigh and masklow from the beginning, i suppose it will be finished. However when lowbit is bigger than highbit, it generate wrong result. Therefore, finally execute 'and' operation with masklow variable*/ int maskhigh=((~0x0)<<highbit)<<1; //make bitmask of highbit int masklow=((~0x0)<<lowbit); //make bitmask of lowbit int tmp_result=(maskhigh^masklow); // ir's value is temporal bitmask int result = tmp_result&masklow; //it used to make 0 when lowbit is bigger than highbit. return result; //return result value } /* * bitParity - returns 1 if x contains an odd number of 0's * Examples: bitParity(5) = 0, bitParity(7) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 20 * Rating: 4 */ int bitParity(int x) { /*i use two property. first, xor make from two of 1 to 0. second, odd -2 = odd, and even -2 = even. computer recognize 0 as even, and 1 as odd. Therefore, when fold as half and execute xor operation again and again, finally remain 0 or 1*/ int result; //variable to result value x=x^(x>>16); //fold as half and xor operation and save to x x=x^(x>>8); //fold as half and xor operation and save to x x=x^(x>>4); //fold as half and xor operation and save to x x=x^(x>>2); //fold as half and xor operation and save to x x=x^(x>>1); //fold as half and xor operation and save to x result=x&0x1; //check LSM of x is 1 or 0 return result; //return result value } /* * isEqual - return 1 if x == y, and 0 otherwise * Examples: isEqual(5,5) = 1, isEqual(4,5) = 0 * Legal ops: ! ~ & ^ | + << >> * Max ops: 5 * Rating: 2 */ int isEqual(int x, int y) { /*At our's book ,computer system, this formula already exist. when x and y is same. x^y value is 0 Therefore, first, execute x^y operation and execute ! operation is to be solution to this practice.*/ int result = !(x^y); //execute operation return result; //return result value } /* * isNonZero - Check whether x is nonzero using * the legal operators except ! * Examples: isNonZero(3) = 1, isNonZero(0) = 0 * Legal ops: ~ & ^ | + << >> * Max ops: 10 * Rating: 4 */ int isNonZero(int x) { /*I use the notion that only 0's signbit is net changed whenever value is positive or negative. Execute 'or' operation with x and -x, and extract signbit. if x is 0, extracted value is 0, otherwise 1. */ int result = ((x|(~x+1))>>31)&1; //execute formula return result; //return result value } /* * sum3 - x+y+z using only a single '+' * Example: sum3(3, 4, 5) = 12 * Legal ops: ! ~ & ^ | << >> * Max ops: 16 * Rating: 3 */ /* A helper routine to perform the addition. Don't change this code */ static int sum(int x, int y) { return x+y; } int sum3(int x, int y, int z) { /*Because i'm already study logical circuit, i use the notion that full adder that consist of 'sum' and 'carry' to solve this practice. To make Boolean Algebra of sum and carry, i use the Karnaugh Map, and make it. sum is 1 when each line of bit of 1's number is odd, otherwise 0 ex)001 011 ---- 010 carry is 1 when each line of bit of 1's number is even, otherwise 0 ex)011 011 ---- 011 finally using 'left shift', carry is added to sum*/ int word1 = (~x&(y^z))|(x&(~y^z)); //indicate 'sum' int word2 = ((x&y)|(y&z)|(x&z))<<1; //indicate 'carry' /************************************************************** Fill in code below that computes values for word1 and word2 without using any '+' operations ***************************************************************/ /************************************************************** Don't change anything below here ***************************************************************/ return sum(word1,word2); //return result value } /* * 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) { /*i use two step to solve this practice first, using 0x11111111 and shift operation, count each place of 1 briefly. two, sum 1's counting to some space and return*/ int tool=0x11; //variable for count 1's number int tmpresult=0; //variable to save temporal value int result=0; // variable to return final value tool=tool^(tool<<8); //using shift, to make 0x11111111 tool=tool^(tool<<16); //using shift, to make 0x11111111 tmpresult=x&tool; //count 1's number ex) 0001 tmpresult+=((x>>1)&tool); //count 1's number ex) 0010 tmpresult+=((x>>2)&tool); //count 1's number ex) 0100 tmpresult+=((x>>3)&tool); //count 1's number ex) 1000 tmpresult=(tmpresult>>16)+tmpresult; //fold as half and add to concentrate to right space //ex) 0x'12121212' to 0x1212'2424' result=(tmpresult&0xf); //extract 1's number and save to result variable //ex) 0x00000003 result+=((tmpresult>>4)&0xf); //extract 1's number and save to result variable //ex) 0x00000030 result+=((tmpresult>>8)&0xf); //extract 1's number and save to result variable //ex) 0x00000300 result+=((tmpresult>>12)&0xf); //extract 1's number and save to result variable //ex) 0x00003000 return result; //return result value } /* * sm2tc - Convert from sign-magnitude to two's complement * where the MSB is the sign bit * Example: sm2tc(0x80000005) = -5. * Legal ops: ! ~ & ^ | + << >> * Max ops: 15 * Rating: 4 */ int sm2tc(int x) { /* to solve the practice, i use practice that already was answered at function tc2sm, reversing of tc2sm is as almost same as solution for this practice. */ int sign_deleted_x; //variable to first operation. int for_1s_complement; //variable to second operation. int plus_signbit; //variable to final operation. int result; //variable to result value. //first, delete the sign bit by '&' oreration with 0x7fffffff. sign_deleted_x=(~(1<<31))&x; /*second, make 'sign_deleted_x' to original value with sign bit. if sign bit is 0, than sign_deleted_x with '^' operation by 'x>>31' will remain same as sign_deleted_x. if sign bit is 1, than sign_deleted_x with '^' operation by 'x>>31' will be 1's complement.*/ for_1s_complement=(sign_deleted_x^(x>>31)); /*finally, plus signbit to 'for_1s_complement' is completed. if signbit is 0, for_1s_complement add 0, and will be completed to original value. if signbit is 1, for_1s_complement add 1, and will be completed to original value by 1's complement and plus 1 is 2's complement.*/ plus_signbit=for_1s_complement+((x>>31)&0x1); result = plus_signbit; //save final value to result variable return result; //return result value }