CSAPP:第2章 信息的表示和处理

CSAPP:第2章 信息的表示和处理

  • 第二章勉勉强强读完了,第一遍读,有部分地方不太理解或者理解不透彻的,望指出
2.1 信息存储
2.1.1 十六进制表示法
  • 主要讲了进制转换,如二进制如何转16
2.1.2 字数据大小
  • 字长点概念——指明指针数据的标称大小(nominal size)
  • 两种伪指令的特性与兼容性问题——一般是64兼容32,如下所示:
    • linux>gcc -m32 prog.c
    • linux>gcc -m64 prog.c
2.1.3 寻址和字节顺序
  • 1、大、小端法
    • 大端=顺序存
    • 小端=以字节为单位反着存
    • image-20210109213601932
  • 有一个比较有意思的点:
    • 芯片可以兼容大小端,但是特定的OS只支持一种——Android和IOS只支持小端
  • 需要考虑字节顺序的三种情况
    • 1、网络传输时(系统间传输可能存在大小端不同的问题,故需要协议作为中介)
    • 2、阅读表示整数数据时
    • 3、编写规避正常类型系统的程序时
2.1.4 表示字符串
  • 用char数组(ascii码)+最后一个终止字节(0x00)
2.1.5 表示代码
  • 由于不同机器类型使用互不兼容的指令和编码方式,即使是完全一样的进程,运行在不同操作系统上也会有不同的编码规则——二进制代码时不兼容的,因此很少有二进制代码在不同及其系统组合之间移植,如:win与linux
2.1.6 布尔代数简介
  • 四种布尔运算:~ & | ^
  • 分别表示:取反、AND、OR、异或
2.1.7 C语言中的位级运算
  • 同上四种
2.1.8 C语言中的逻辑运算
  • 分别为:&& || !
  • 常见的,需要注意的是逻辑运算的结果只能是0、1,即TURE、FALSE
2.1.9 C语言中的移位运算
  • <<为左移, >>为右移
  • C中并没有明确规定右移的类型(逻辑还是算数),该问题可能导致可移植性问题——不同系统的定义不同
  • Java中 >> 表示算数右移,>>>表示逻辑右移
  • C语言中 加减法的优先级比移位高
2.2 整数表示
  • 符号含义,本小节我读的很痛苦,究其本质就是忘看这段符号,导致很多简单公式愣了好一会
1E6F9C27DDD3223D7AC4FD985F103923
2.2.1 整型数据类型
  • 分为有符号和无符号两种,其中C、C++默认有符号,但支持无符号,Java只支持有符号
2.2.2 无符号数的编码
  • B2Uw=Bin are to Unsigned
  • 这个公式就是位数*权重,且最高位不是符号
  • image-20210109231731844
  • 书中还提到一个概念,双射,即y=f(x),xy一一对应,不存在一对多、多对一的情况
2.2.3 补码编码
  • B2Tw=Binary to Two’s-complement

  • Two’s-complement=补码

  • 该公式与无符号的区别是最高位的权重是-1而不是1,这是由补码的特性决定的(1=负),补码也是双射

  • image-20210109232352633
  • 但是 反码和原码不是双射——0的两种表示方法(±0)

2.2.4 有符号数和无符号数之间的转换
  • C语言中的强制类型转换只是改变了解释这些位的方式,而不改变位置上的值,尤其是对最高位来说。
  • 转换公式
    • 就我自己来说,我一般是化为二进制再转。而书中的公式是:
    • 补码转无符号
      • image-20210109233926014
    • 无符号转补码
      • image-20210109234019580
2.2.5 C语言中的有符号数与无符号数
  • int和unsigned
2.2.6 拓展一个数字的位表示
  • 无符号数=0扩展(补0即可)
  • 补码数=最高位扩展(补最高位的值)
    • 有意思的是书上还给了证明,我的理解就是对于负数的补码,把权重带进去就可以证明是正确,对于正数就是0扩展
      • image-20210109234421960
2.2.7 截断数据
  • 无符号数的截断就是留下低位即可
  • 补码的截断类似无符号数,但是取低位的最高位作为符号为
2.2.8 关于有符号数与无符号数的建议
  • 转换要指明,隐式转换,最为致命。
2.3 整数运算
2.3.1 无符号数加法
  • 它实际上是这样的一个梯形上升,而不是平滑曲面,因此需要稍微考虑正溢出的问题。
  • image-20210109235204715
  • 相关公式是:
  • image-20210109235313047
2.3.2 补码加法
  • 补码由于有正、负,因此需要考虑正、负溢出。下图为补码溢出情况,个人觉得有必要了解下(大致范围)
  • image-20210109235949174
  • 下面T2U的公式转换参见上面补码表示的公式
  • image-20210109235720345
2.3.3 补码的非
  • ~ 每位都取反 如:1000 --> 0111 === -8 -->7
  • 因此可以得倒一个有趣的东西:-x = ~x+1
  • 其公式如下:
  • image-20210110000527345
2.3.4 无符号乘法
  • 下面公式中mod作用是取低位
  • image-20210110000612120
2.3.5 补码乘法
  • 公式如下:
  • image-20210110000832133
  • 补码乘法有一个特性,即无符号数与补码乘法的位级等价性,说人话就是:低位相同
  • 推到过程是,我个人还是不太喜欢这种纯理论,书下方有几道联系,做完你会发现确实如此:
  • image-20210110000941196
2.3.6 乘以2的幂
  • 乘以2的幂=右移位,高位丢弃
  • image-20210110001219473
  • 关于补码乘以2的幂,需要考虑一出的问题(正变负这种)
2.3.7 除以2的幂
  • 相当于左移
2.4 浮点数
2.4.1 二进制小数
  • 尾数与阶数,讲了一般意义上的小数的表示
2.4.2 IEEE浮点表示
  • 这里介绍了两种,分别是(符号位、阶码位数、尾数位数),其中,尾数一般有一个隐藏的1
    • float:1,8,23
    • double:1,11,52
  • 这里的浮点数一般有三种情况
    • 1、规格化的浮点数
      • 阶码E = e - Bias (对于Bias有 float=127 ,double是1023)
    • 2、非规格化的值
      • 对于这里我有点不理解,为什么会平滑转换,我翻了很多网上童鞋的笔记,发现没有指出的,希望有缘人能解个惑~
      • 目前的知道的是他把尾数隐藏的1用来给E+1了
      • image-20210110002534661
      • 当表示非常接近0.0的数的时候,非规格化值会表现出一个特性——逐渐下溢(精度丢失?)
    • 3、特殊值
      • 当阶码全1的时候出现
        • 当尾数全0 === ∞
        • 当尾数非0 === NAN(not a number)
          • 比如根号-1的结果就是NAN,或者∞-∞也是
2.4.3 数字示例
  • 下图可以表示出越接近0,数越密集,则可以越平滑地过渡到0
  • image-20210110003151587
  • 下图印证了2.4.2的说法
  • image-20210110003336304
2.4.4 舍入
  • 有以下四种常用舍入方式
  • image-20210110003439025
  • 其中,像偶数舍入有点像我们常说的四舍五入
2.4.5 浮点运算(留坑)
  • 关于这里我有点不明白阿贝尔群,这个概念我到现在还没懂(毕竟是菜鸡),流坑
  • 常见流程无非就是:对阶-尾数运算-舍入-规格化,还有个溢出判定
  • 浮点加法不具有结合性,满足单调性
2.4.6 C语言中的浮点数
  • 有float和double,对于特殊值有专门定义,如INFINITY(∞),NaN(NAN)
2.5 小结
  • 重复以上。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

椰子奶糖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值