Jason Zhou的Coding之路 凡是过往皆为序章

深入理解计算机系统学习笔记一


操作系统原理的书几乎没有太多实践,也缺乏和计算机组成相关的东西,大部分理论的东西算是过了一遍,后面可能要看些《深入理解计算机系统》的内容。后面这本书相关内容,就不再做归纳了,只是对之前不了解或不懂的地方练一遍顺便在这里记录下来。

本篇主要是关于数的存储,数的相关运算等。

整数储存

  • 0x 代表一个十六进制的数,忽略大小写。类似 0xFA1D37B0xfa1d37b0xFa1d37B 是一样的。
  • o 代表八进制
  • 储存规则:大端法(数的高位先存)和小端法(数的低位先存)。(字节为单位的移动,字节内顺序是否变化未知)
  • ascii 码中十进制数字 i 编码为 0x3i,大写字母起始位 0x41,小写字母起始为 0x61。

整数计算

  • 算术右移(补最高位)和逻辑右移(补 0)。C 语言编译器一般是默认算数右移。Java 有»>来作为逻辑右移。C 语言可通过把数声明为无符号的来实现逻辑右移。
  • 如果左移右移的位数过大,会对位数取余数。
  • 位移运算优先级低于普通运算。高于判断和位运算,逻辑运算,赋值运算等。
  • 补码两种思考方式:
    1. 全部取反再加 1。例如-1 由 1 全部取反在做无符号数字的加法运算加 1。
    2. 负的最高位数值在加上正的其余位的数值。例如-1,则是 $-2^{31} + 2^{30} + 2^{29}+ \cdot + 2^{0}$
  • 补码原理:补码编码具有唯一性。具有可逆性。C 语言没有要求用补码形式存储有符号数,而 Java 要求用补码形式存储数据。
  • 有无符号的转换采用”位不变原则”。运算的隐式转换无符号运算(者会导致比较运算出问题, 有符号和无符号比较要小心,无符号的计算也可能出错(特别是减出赋值,加出更小的值))。所以除了 C 语言以外,很少有语言支持无符号整数。
  • short->unsigned: (unsigned) (int) sx;当符号和数据长度同时改变时,先改变数据长度,再改变符号。
  • 截断只管低位数值,不论有无符号,位不变。
  • 补码的非:就算相反数(全取反+1)-x=~x+1。有两个数取非不变,0 和补码表示的最小值(0x80000000)。也可以理解成
  • 负数的 2 幂次整除,直接用右移不行(算术右移),会出现向负方向取整的问题。 ```cpp int div(int x, int k) { return (x < 0 ? x + (1«k) - 1 : x) » k; }

int div(int x, int k) { int bias = (x » 31) & ((1 « k )- 1); return (x + bias) » k; } ```

小数粗存

  • 小数浮点数的存储的表达式如果解释成整数,正数大小排序和整数的大小排序是相同的。负数浮点数则是降序排列的。所以相同精度的浮点数比较是容易的。
  • 浮点数接近于 0 有”逐渐溢出”的特性。
  • 浮点数有缺乏结合性和分配性的情况。
  • C 会自动将一些计算设置成特殊值,例如溢出成无限大。1/无限大是+0.0, -1/无限大是-0.0 等。无限大的一些运算会变成 NaN。

收获挺多。


Comments

Content