操作系统原理的书几乎没有太多实践,也缺乏和计算机组成相关的东西,大部分理论的东西算是过了一遍,后面可能要看些《深入理解计算机系统》的内容。后面这本书相关内容,就不再做归纳了,只是对之前不了解或不懂的地方练一遍顺便在这里记录下来。
本篇主要是关于数的存储,数的相关运算等。
整数储存
- 0x 代表一个十六进制的数,忽略大小写。类似
0xFA1D37B
,0xfa1d37b
和0xFa1d37B
是一样的。 - o 代表八进制
- 储存规则:大端法(数的高位先存)和小端法(数的低位先存)。(字节为单位的移动,字节内顺序是否变化未知)
- ascii 码中十进制数字 i 编码为 0x3i,大写字母起始位 0x41,小写字母起始为 0x61。
整数计算
- 算术右移(补最高位)和逻辑右移(补 0)。C 语言编译器一般是默认算数右移。Java 有»>来作为逻辑右移。C 语言可通过把数声明为无符号的来实现逻辑右移。
- 如果左移右移的位数过大,会对位数取余数。
- 位移运算优先级低于普通运算。高于判断和位运算,逻辑运算,赋值运算等。
- 补码两种思考方式:
- 全部取反再加 1。例如-1 由 1 全部取反在做无符号数字的加法运算加 1。
- 负的最高位数值在加上正的其余位的数值。例如-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。
收获挺多。