ICS data lab总结

来源:互联网 发布:看腐剧用什么软件 编辑:程序博客网 时间:2024/05/17 02:39

ICS data lab总结


总述

data lab是一个考察整数位运算技巧和实数的浮点数表示位格式的lab,而且还有能使用的符号和符号数量限制。
这些题目自己做下来有一些智力游戏的感觉,而且要考虑的边界情况很多(尤其是0x80000000),有时候自己不知道做错了哪里经常需要利用lab给的举反例工具来举反例看自己错在哪里,然后再修改调试。但是这样一来次数多了,做完以后自己晕乎乎地都不知道对了没有,不像bomb lab做的时候晕乎乎,做完后想一想能清楚很多。所以做完以后我没有急着总结写报告,而是等了很久趁现在空了下来,我回忆了一下我还记得什么,我到底从中学到了什么。


其中值得学习的地方

做完data lab有一种很浓的智力游戏的感觉,虽然这个lab设计地很好很精巧,但是还是要承认,在对数据的二进制表示有一定熟练度以后这个lab大部分题目的应用真的不是很大,练习的技能似乎与实战脱节,至于追求更少op数,我觉得完全是对自己的智力的挑战,为了挑战困难的愉悦而奋斗,实际意义不大。(不过我很崇拜这些op数到了80-的人,一来他们真的很厉害,而来虽然这个没有实际太大意义,可是大学CS学习的东西虽然实用,更重要的内功的积累,所以学习不能太功利,而且享受这些看似无用的东西,遵从自己的兴趣,才能有一段美好的大学生活吧。)
但是其中还有几点很值得我们学习,一是(个别)的整数位运算技巧,比如取整数低位,在树状数组里用得很多,二是浮点数题目,让我们亲自实现加深了我们对IEEE标准的理解。

datalab中出现的整数位运算技巧题目

整数运算技巧主要有:掩码技术,整数运算溢出判断,异或应用,二分统计位级信息等技术。
但是还有一些lab里没有涉及的整数运算技巧,我觉得很重要,网上有很多文章,如果以后要面试什么的之前可以先看一看。

//1/*  * thirdBits - return word with every third bit (starting from the LSB) set to 1 *   Legal ops: ! ~ & ^ | + << >> *   Max ops: 8 *   Rating: 1 */int thirdBits(void) {  int x=0x49;//1001001(8)  x=x|(x<<9);//001001001001001001(18)  x=x|(x<<18);//(36)  return x;}/* * isTmin - returns 1 if x is the minimum, two's complement number, *     and 0 otherwise  *   Legal ops: ! ~ & ^ | + *   Max ops: 10 *   Rating: 1 */int isTmin(int x) {  int t=x+x;  return !(t|(!x));}//2/*  * 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);}/*  * anyOddBit - return 1 if any odd-numbered bit in word set to 1 *   Examples anyOddBit(0x5) = 0, anyOddBit(0x7) = 1 *   Legal ops: ! ~ & ^ | + << >> *   Max ops: 12 *   Rating: 2 */int anyOddBit(int x) {  x|=x>>16;  x|=x>>8;  return !!(x&0xaa);}/*  * negate - return -x  *   Example: negate(1) = -1. *   Legal ops: ! ~ & ^ | + << >> *   Max ops: 5 *   Rating: 2 */int negate(int x) {  return ~x+1;}//3/*  * 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 result=y;  int delta=z+~y+1;  int notx=((!x)<<31)>>31;  result+=delta&notx;  return result;}/*  * subOK - Determine if can compute x-y without overflow *   Example: subOK(0x80000000,0x80000000) = 1, *            subOK(0x80000000,0x70000000) = 0,  *   Legal ops: ! ~ & ^ | + << >> *   Max ops: 20 *   Rating: 3 */int subOK(int x, int y) {  int ans=x+~y+1;  return !(((x^y)&(ans^x))>>31);}/*  * 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) {  int s=(y+~x+1)>>31;  int sx=x>>31;  int sy=y>>31;  return (s&1)^(!(s^sx)&(s^sy));}//4/* * 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) {  x^=x>>16;  x^=x>>8;  x^=x>>4;  x^=x>>2;  x^=x>>1;   return x&1;}/* 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 flag=!(!x|!(x+1));  int s=x>>31;  int x1=x^s;  int x2=x1|(x1>>1);  int x4=x2|(x2>>2);  int x8=x4|(x4>>4);  int x16=x8|(x8>>8);  int x32=x16|(x16>>16);  int l=x32^(x32>>1);  int g16=l>>16;  int l16=(g16|l)&((1<<16)+(~0));  int g8=l16>>8;  int l8=(g8|l16)&0xff;  int g4=l8>>4;  int l4=(g4|l8)&0xf;  int g2=l4>>2;  int l2=(g2|l4)&0x3;  int g1=l2>>1;  int l1=(g1|l2)&1;  return ((!!g16)<<4)+((!!g8)<<3)+((!!g4)<<2)+((!!g2)<<1)+(!!g1)+1+flag;}//float/*  * float_half - Return bit-level equivalent of expression 0.5*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 float_half(unsigned uf) {  unsigned s=uf&0x80000000;  unsigned exp=uf&0x7f800000;  int lsb=((uf&3)==3);  if (exp==0x7f800000)    return uf;  if (exp<=0x800000)    return s|(((uf^s)+lsb)>>1);  if (exp)    return (uf-0x800000);}

datalab中出现的浮点数位级表示题目

本次data lab是以下三个题,尤其要注意的是float_i2f这个题先左移整数在统一右移处理避开了
左移还是右移的分类讨论,也避开了是否round的分类讨论,统一处理了,何其优雅!这个思路来自网络看了别人的文章加上我对IEEE标准的理解。还有一些round_to_even的细节,值得回味。

//float/*  * float_half - Return bit-level equivalent of expression 0.5*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 float_half(unsigned uf) {  unsigned s=uf&0x80000000;  unsigned exp=uf&0x7f800000;  int lsb=((uf&3)==3);  if (exp==0x7f800000)    return uf;  if (exp<=0x800000)    return s|(((uf^s)+lsb)>>1);  if (exp)    return (uf-0x800000);}/*  * float_i2f - Return bit-level equivalent of expression (float) x *   Result is returned as unsigned int, but *   it is to be interpreted as the bit-level representation of a *   single-precision floating point values. *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while *   Max ops: 30 *   Rating: 4 */unsigned float_i2f(int x) {  unsigned sign=0,frac;  int exp,flag,last,round,stick;  if (x==0)    return 0;  if (x<0)    sign=0x80000000;  if (sign)    frac=-x;  else    frac=x;  exp=158;  while (!(frac&0x80000000)) {    exp--;    frac<<=1;  }  last=(frac>>8)&1;  round=(frac>>7)&1;  stick=frac&0x7f;  flag=(round&&stick)||(round&&!stick&&last);  frac=(frac<<1)>>9;  frac+=flag;  if (frac>=0x800000) {    frac=((frac+0x800000)>>1)-0x800000;    exp+=1;  }  return (sign|(exp<<23)|frac);}/*  * float_f2i - 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 float_f2i(unsigned uf) {  int sign=uf>>31;   int exp=(uf>>23)&0xff;  int frac=uf&0x007fffff;  int right=157-exp;  int abs;  if (exp<0x7f)    return 0;  if (exp>157)    return 0x80000000;  abs=(0x40000000+(frac<<7))>>right;  if (sign)    return -abs;  else     return abs;}
0 0