数据表示
- 位操作
- 基本运算
- 与、或、非、异或、左移。
- 逻辑右移:在高位补 。
- 算术右移:在高位补充之前的最高位数字。
- 移位量大于等于字长或小于 在 C 语言中是未定义行为。
- 优先级
- 位运算符优先级:
- 按位非
~ - 左移/右移
<<>> - 按位与
& - 按位异或
^ - 按位或
|
- 按位非
- 结合算术运算时,算术运算符优先级高于移位运算符。
- 位运算符优先级:
- 基本运算
- 内存布局
- 字长
- 字长等于 CPU 的位数。
- 地址按照字长的倍数对齐。
- 字节顺序
- 字节顺序指定多字节数据类型中每个字节的顺序。
- 大端序:高位在前,低位在后。Internet 使用。
- 小端序:高位在后,低位在前。x86、ARM 使用。
- 字长
- 整数
- 编码
- 二进制位向量:底层储存方式,无编码,以下用 表示,记作 。
- 无符号整数:把二进制位向量直接解释为整数,以下用 表示。
- 有符号补码整数:最高位作为符号位,剩下的位储存数或其按位取反加 ,以下用 表示。
- C 语言标准不强制有符号整数使用补码,但是几乎都是使用补码。
- 编码解释
- 对于同一个位向量,使用不同的编码,可以有不同的解释的值。
- 无符号 。
- 有符号
- 逆运算用 、 表示。
- 无符号最值 ,。
- 补码最值 ,。
- 同大小强制转换
- 基本原则:在补码和无符号之间转换,底层的位向量不会变,只是改变编码方式。
- 补码转无符号 。
- 非负数和负数转换后,区间顺序颠倒,负数变成大正数。
- 非负数值不变, 转换为 , 转换为 。
- 无符号转补码 。
- 在同一个运算符两侧,如果同时存在无符号和补码,则会转换补码为无符号,再进行比较。
- 扩展
- 基本原则:扩展前后,整数的值都不变。
- 无符号
- 直接在最高位前补 。
- 补码
- 在最高位前复制最高位,保证符号不变,这种机制叫符号扩展。
- 截断
- 基本原则:截断都在位级别保留最低的若干位,再重新解释为值。
- 无符号 。
- 补码 。
- 加法
- 基本原则:无符号和补码的加法在位级别上一样,均截断理论结果的位向量。
- 无符号 。
- 补码 。
- 乘法
- 基本原则:无符号和补码的乘法法在位级别上一样,均截断理论结果的位向量。
- 无符号 。
- 补码 。
- 如果两个 位整数相乘,则精确表示结果需要 位。
- 移位实现的乘除法
-
<< -
>> - 对于有符号数,实现向 取整除法:
>>。
-
- 编码
- 浮点数
- 编码
- IEEE 754 浮点数的二进制表示分为三部分:符号位 、阶码 、尾数 。
- 分别对应 的符号位 、指数 、尾数 ,但彼此不直接相等。
- 精度:
- 单精度:32 位,阶码用 8 位,尾数用 23 位。
- 双精度:64 位,阶码用 11 位,尾数用 52 位。
- Normalized Value:
- 为全 和 全 时,浮点数是 Normalized Value。
- 阶码用偏置编码指数,,其中 , 为阶码长度。
- 尾数表示为 , 直接使用尾数部分的二进制串。
- Denormalized Value:
- 全为 时,浮点数是 Denormalized Value。
- 指数规定为 。
- 尾数表示为 。
- 无穷大: 全为 , 为全 。
- NaN: 全为 , 不为全 。
- IEEE 754 浮点数的二进制表示分为三部分:符号位 、阶码 、尾数 。
- 舍入
- 四种舍入方式:
- 向下舍入
- 向上舍入
- 向零舍入
- 向偶数舍入:类似四舍五入,除了当被舍入的最高位为一半时,向被保留的最后一位的偶数方向舍入。
- 和 都舍入为 。
- 二进制下的向偶数舍入:
- 仅当出现 时,需要特殊考虑舍入方向
- 舍入向最后一个 为 的方向。
- 四种舍入方式:
- 加法
- 设浮点数 ,且 ,则加法按照以下步骤:
- 把 与 对齐,即 ,结果的阶码则为 。
- 相加 与 ,得到 。
- 根据 修正结果:
- 如果 ,则 右移除以 ,递增 。
- 如果 ,则 左移 位, 减去 ,要求最后结果满足尾数的定点数格式。
- 如果 超出范围,则其饱和溢出,即最终结果表示为无穷大。
- 舍入 到合适的精度。
- 代数性质:
- 不满足结合律。
- 基本可逆,除了无穷大和 NaN。
- 基本满足单调性 ,除了无穷大和 NaN。
- 设浮点数 ,且 ,则加法按照以下步骤:
- 乘法
- 设浮点数 ,则乘法按照以下步骤:
- 计算符号位 。
- 计算指数 。
- 计算尾数 。
- 根据 修正结果、处理溢出和舍入,方法同加法。
- 代数性质:
- 不满足结合律。
- 对加法不满足分配律。
- 基本满足单调性 ,除了无穷大和 NaN。
- 设浮点数 ,则乘法按照以下步骤:
- 编码