Skip to main content

csapp 第2章 信息存储 整数浮点数

·209 words·1 min· loading · loading ·
Author
Tab_1bit0
咕咕咕

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() 注意分类讨论

 CS61b学习总结 attackLab 

comments powered by Disqus