CSAPP data Lab
来源:互联网 发布:表单向php提交数据 编辑:程序博客网 时间:2024/05/17 00:58
CSAPP data Lab
注意,本文代码出于节省括号避免繁杂的考虑,对运算符优先级利用得比较充分,比如 1>>n+1 等价于 1>>(n+1),所以代码里写了1>>n+1。
bitAnd
/* * bitAnd - x&y using only ~ and | * Example: bitAnd(6, 5) = 4 * Legal ops: ~ | * Max ops: 8 * Rating: 1 */int bitAnd(int x, int y) { return ~(~x|~y);}
思路
- 德摩根定律
getByte
/* * 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) { int bias = n<<3; return (x>>bias)&0xFF;}
思路
- 移位到最低的1byte然后用0xFF提取
logicalShift
/* * logicalShift - shift x to the right by n, using a logical shift i * Can assume that 0 <= n <= 31 * Examples: logicalShift(0x87654321,4) = 0x08765432 * Legal ops: ! ~ & ^ | + << >> * Max ops: 20 * Rating: 3 */int logicalShift(int x, int n) { return (1<<32+~n<<1)+~0 & (x>>n); //equal to ((1<<31-n<<1)-1)&(x>>n); //负号优先级高于移位}
思路
因为不能用
-
,所以用取反加一代替取负构造低
32-n
bit的1来提取移位后的数值因为移位量不能小于0或大于等于32,所以对于n可能是0而导致移位量是32的情况,先移位31位,再移位1位
小技巧,如果n移位k,k
∈ [0, 32],则可以n>>(k-!!k)>>!!k
bitCount
/* * 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) { int mark1 = 0x55; int mark2 = 0x33; int mark3 = 0x0F; mark1 |= mark1<<8; mark1 |= mark1<<16; mark2 |= mark2<<8; mark2 |= mark2<<16; mark3 |= mark3<<8; mark3 |= mark3<<16; x = (x>>1&mark1)+(x&mark1); //every two bits; clear record; x = (x>>2&mark2)+(x&mark2); //every four bits; clear record; x = (x>>4&mark3)+(x&mark3); //every eight bits; clear record; x = (x>>8)+x; //every 16 bits; record in the low 8 bits; x = (x>>16)+x; //every 32 bits; record in the low 8 bits; return x&0xFF;}
思路
- 构造0x55555555,提取每两位中的low bit。通过移位及0x55555555,提取每两位中的高位。然后相加,使得结果中,每两位的二进制值就是该两位的bit数目
- 同样的思路,提取每四位的low bit、high bit,然后相加
- 因为32==100000(二级制),也就是只需要5位就可以记录有多少bit数,所以不需要每次都构造常数屏蔽高位的值,直接移位相加然后取低8bit就可以得到最终结果
bang
/* * bang - Compute !x without using ! * Examples: bang(3) = 0, bang(0) = 1 * Legal ops: ~ & ^ | + << >> * Max ops: 12 * Rating: 4 */int bang(int x) { x |= x>>1; x |= x>>2; x |= x>>4; x |= x>>8; x |= x>>16; return ~x&0x1;}
思路
- 如果非0,位模式从最高位的1到最低位都填充为1,
- 如果为0,则位模式还是保持全0
tmin
/* * tmin - return minimum two's complement integer * Legal ops: ! ~ & ^ | + << >> * Max ops: 4 * Rating: 1 */int tmin(void) { return 1<<31;}
fitBits
/* * fitsBits - return 1 if x can be represented as an * n-bit, two's complement integer. * 1 <= n <= 32 * Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 15 * Rating: 2 */int fitsBits(int x, int n) { return !(x>>n+~0)|!((x>>n+~0)+1); //equal to !(x>>n-1) | !((x>>n-1)+1)}
思路
- 算术移n-1位,如果是负数,且可以用n bits的补码表示,则得到-1。如果是正数,则得到0。
divpwr2
/* * 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) { int t = x>>31; return (x+(t&1<<n)+(~(t&1)+1))>>n; //equal to (x+(t&1<<n)-(t&1))>>n; //note that & 的优先级低于<<}
思路
- 直接移位是round down,无论是负数还是正数
- 所以要实现round to zero , C表达式为
x<0 ? x+(pow(2,n)-1)>>n : x>>n
negate
/* * negate - return -x * Example: negate(1) = -1. * Legal ops: ! ~ & ^ | + << >> * Max ops: 5 * Rating: 2 */int negate(int x) { return ~x+1;}
思路
- 直接取反再加1
isPositive
/* * isPositive - return 1 if x > 0, return 0 otherwise * Example: isPositive(-1) = 0. * Legal ops: ! ~ & ^ | + << >> * Max ops: 8 * Rating: 3 */int isPositive(int x) { return ~(x>>31)&!!x;}
思路
- 符号位判断,并且非0
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) { return !!(x>>31&~(y>>31)) | !(~(x>>31)&(y>>31))&(x+~y+1>>31) | !(x^y); //equal to !!(x>>31&~(y>>31)) | !(~(x>>31)&(y>>31))&(x-y>>31) | !(x^y)}
思路
x<0&&y>0 | !(x>0&&y<0)&&(x-y>0) | x==y
ilog2
/* * ilog2 - return floor(log base 2 of x), where x > 0 * Example: ilog2(16) = 4 * Legal ops: ! ~ & ^ | + << >> * Max ops: 90 * Rating: 4 */int ilog2(int x) { int mark1 = 0x55; int mark2 = 0x33; int mark3 = 0x0F; mark1 |= mark1<<8; mark1 |= mark1<<16; mark2 |= mark2<<8; mark2 |= mark2<<16; mark3 |= mark3<<8; mark3 |= mark3<<16; x |= x>>1; x |= x>>2; x |= x>>4; x |= x>>8; x |= x>>16; x >>= 1; x = (x>>1&mark1)+(x&mark1); //every two bits; clear record; x = (x>>2&mark2)+(x&mark2); //every four bits; clear record; x = (x>>4&mark3)+(x&mark3); //every eight bits; clear record; x = (x>>8)+x; //every 16 bits; record in the low 8 bits; x = (x>>16)+x; //every 32 bits; record in the low 8 bits; return x&0xFF;}
思路
- 先构造从最高的1到最低位均为1的二进制,然后类似bitCount
float_neg
/* * float_neg - Return bit-level equivalent of expression -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 representations of * single-precision floating point values. * When argument is NaN, return argument. * Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while * Max ops: 10 * Rating: 2 */unsigned float_neg(unsigned uf) { unsigned t = uf&0x7FFFFFFF; if(t^0x7F800000 && (t>>23)+1>>8) return uf; else return uf^0x80000000;}
思路
- 判别是否是NaN。先判断尾数是否全0,然后用
(t>>23)+1>>8
判断exp是否全1
float_i2f
/* * 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 shiftLeft=0; unsigned afterShift, tmp, flag; unsigned absX=x; unsigned sign=0; //special case if (x==0) return 0; //if x < 0, sign = 1000...,abs_x = -x if (x<0) { sign=0x80000000; absX=-x; } afterShift=absX; //count shift_left and after_shift while (1) { tmp=afterShift; afterShift<<=1; shiftLeft++; if (tmp & 0x80000000) break; } if ((afterShift & 0x01ff)>0x0100) flag=1; else if ((afterShift & 0x03ff)==0x0300) flag=1; else flag=0; return sign + (afterShift>>9) + ((159-shiftLeft)<<23) + flag;}//from http://www.cnblogs.com/tenlee/p/4951639.html
思路
分情况处理0、负数、正数
要处理舍人
- 向接近的舍入
- 如果处于中间,向偶数舍入
舍入时,如果尾数加一,exp有可能需要进位,这时候直接加一效果一样,可以导致exp进位,不需要特殊处理。如果exp等于0xFE,那么进位就变成了inf,也是合法的
float_twict
/* * float_twice - 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 float_twice(unsigned uf) { unsigned t = uf&0x7FFFFFFF; unsigned temp = t&0x7F800000; unsigned temp2 = uf&0xFF800000; int expFull = !(temp^0x7F800000); if(t^0x7F800000 && expFull) return uf; if(expFull){ return temp2; } if(!(t&0x7F800000)){ unsigned k = (uf&0x7FFFFF); return temp2+(k<<1); } return (temp>>23)+1<<23 | uf&0x807FFFFF;}
思路
- 分情况处理三种IEEE754的情况
- 需要注意exp全0时,乘以二就是尾数乘以二,如果发生进位需要exp进位,不需要特殊处理(第三个if),因为进位直接导致exp加一,这就足够了
阅读全文
0 0
- CSAPP Data Lab
- CSAPP data Lab
- CSAPP LAB---Proxy lab
- <csapp> data lab (《深入理解计算机系统》lab1)
- CSAPP: bomb lab
- CSAPP: buffer lab
- CSAPP: shell lab
- CSAPP: malloc lab
- CSAPP LAB---MALLOC实验
- CSAPP LAB---shlab-handout
- 【CSAPP】malloc Lab
- CSAPP: Malloc Lab 7
- CSAPP: Buffer Lab
- CSAPP: Architecture Lab
- CSAPP: Cache Lab
- CSAPP: Shell Lab
- CSAPP: Malloc lab
- CSAPP: Proxy lab
- CSS3背景、渐变、蒙版
- 24. Swap Nodes in Pairs
- CSAPP Bomb Lab
- LabVIEW 视觉软件 发布部署 要点
- Android View事件分发机制 三 (Activity)
- CSAPP data Lab
- JAVA中日期 yyyy-MM-dd HH:mm:ss和yyyy-MM-dd hh:mm:ss的区别
- 小随笔:写一个基于几何生成方法的描边效果
- HashMap和TreeMap
- CSS3分栏、响应式布局
- CSS基本选择器
- Eclipse Neno版本 安装插件开发JavaEE
- php数据库的关联设计
- Unity动态创建带有Shader的Material