02 bits-ints-part2 数据的运算 | CSAPP

123 阅读2分钟

Overview

数据的运算

按位运算和逻辑运算

移位运算

位扩展和位截断运算

无符号和带符号整数的加减运算

无符号和带符号整数的乘除运算

变量与常数之间的乘除运算

浮点数的加减乘除运算

整数加法

无符号:不溢出直接加,溢出减掉溢出第一位权重。

有符号:不溢出直接加,正溢出真实结果减掉溢出位权重,负溢出加上溢出第一位权重

整数乘法

无符号:溢出直接截断

有符号:溢出直接截断

有符号无符号位级运算等价

有时乘法可以用移位与加法来优化

左移:乘 2 的位移数次方

整数除以 2 的幂

算数右移:除以 2 的位移数次方(向下取整)

算术右移加偏置:给原数字加上 2 的位移数次方再减 1 ,最后除以 2 的位移数次方(向上取整)

注意:C 语言中的整型除法是向零舍入,负数 xx 除以 2k2^k 要写为 x+2k1x+2^k-1 除以 2k2^k ,用位移运算写为 (x+(1<<k)-1)>>k

浮点数

IEEE 浮点数的表示

V=(1)s×M×2EV=(-1)^{s}\times M\times 2^{E}
  • ss 由符号位表示,0 表示正数,1 表示负数
  • MM 由小数字段表示,单精度浮点的小数字段是 23 位,双精度浮点的小数字段是 52 位
  • EE 由阶码(exponent)减去偏移量表示,expexp 是阶码,单精度阶码 8 位,双精度阶码 11 位

根据阶码 expexp 的取值类型,被编码的浮点数值被分为三种类型:

1. 规格化的值(Normalized value)

阶码 expexp 既不全为 1 也不全为 0

M=1+fM=1+f 有前导 1

exp=E+2k11exp = E + 2^{k-1} - 1 其中 kk 为阶码的位数,偏置量的含义为指数的取值范围,即 (2k12)+(2k11)-(2^{k-1}-2)\sim +(2^{k-1}-1) ,也就是用无符号数表示指数。最大值是阶码最高位为 0 除此以外全为 1 ,最小值是阶码最低位为 1 除此以外全是 0

速记:单精度浮点的偏置量为 127(x811)127\,(x^{8-1}-1) ,双精度浮点的偏置量为 1023(21111)1023\,(2^{11-1}-1)

2. 非规格化的值(Denormalized value)

阶码的每一位全为 0

M=fM=f 没有前导 1

exp=0E=1Bias=2k1+2exp=0\quad E=1-Bias=-2^{k-1}+2

3. 特殊值(Special value)

阶码的每一位全为 1

当小数字段全为 0 时表示为无穷大

当小数字段非零时表示为 NaNNaN 不是一个数

舍入

向偶数舍入:四舍六如,最低为是五保证最低有效位是偶数

浮点运算

可交换

不可结合(溢出)

单调

不可分配(溢出)