CSAPP Learning#
认知上的一些补充#
对于一个32位(4B)的数字——
- 不同机器上的big/little endian 的存储方法不同
- 可以有很多种不同的解释方法
- unsigned
- int
- float
- 一个同样的二进制序列,在不同的数据类型下的含义不尽相同。
位运算的奇妙功能——
- & : 可以取出特定位上的数字
- ^ : 可以检查和模具的契合度,!(a ^ b)的方法可以实现匹配相等检测
- ! : 可以将繁杂的int32归拢成为0和1
- | : 可以归并条件的「或」
- ~ : 可以取二进制补码,快速得到逆元
- « and » : 可以快速推拉一个二进制数
浮点数的精妙设计——
- 符号+exp+frac
- unnormalized与normalized之间的平滑过渡
- bias的引入(=127 for float)
- 有效数字的概念挪移
- 对正负无穷大与NaN的复现方法
一些可能性的拓展……
- 二进制的加减乘除,浮点数的处理,在底层的数字电路板子上如何设计实现?
- 从线性代数的角度审视,这些运算是否能抽象成在0/1的特殊n维空间上的矩阵向量运算?
DataLab#
主要由前半部分的integer操作和后半部分的float功能复现构成。
前半部分更偏向思维性,后半部分更偏向工程性。
对构造的思维方法会要求比较高。
allOddBits()#
题干要求只能出现0x00-0xff区间内的数字,但我们却需要一个0xAAAAAAAA。
int root = 0xAA;int mask = root<<24 | root<<16 | root<<8 | root;
拼起来就可以啦
isAsciiDigit()#
!!((~x+0x30) & 1<<31) & !((~x+0x3a) & 1<<31)
区间内正负性的判断
conditional()#
(y & !!x<<31>>31) | (z & !x<<31>>31)
简单的推拉复制。
isLessOrEqual()#
!(!(x & 1<<31) & !!(y & 1<<31)) & (!!((x+~y) & 1<<31) | (!!(x & 1<<31) & !(y & 1<<31)))
记得写特判喵,还有这里可以拆开写,这个格式不太好
howManyBits()#
这是一个很巧妙的二分处理法
int sign = x >> 31;
x = sign ^ x;
b16 = !!(x >> 16) << 4;
x = x >> b16;
b8 = !!(x >> 8) << 3;
x = x >> b8;
b4 = !!(x >> 4) << 2;
x = x >> b4;
b2 = !!(x >> 2) << 1;
x = x >> b2;
b1 = !!(x >> 1);
x = x >> b1;
b0 = x;
return b16 + b8 + b4 + b2 + b1 + b0 + 1; 不用枚举32遍的
这个代码不是我写的,哈Gemi的比我写的整洁
还有三个Float的功能复现,思维难度相比不大
- floatFloat2Int() 特判+映射+加符号组合拳
- floatPower2() 注意分类讨论
