ICS data lab总结

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¬x;
  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;
}

你可能感兴趣的:(Computer,System)