CMU 15-213 Intro to Computer Systems Lecture 4
课程主页:http://www.cs.cmu.edu/afs/cs/academic/class/15213-f15/www/schedule.html
课程资料:https://github.com/EugeneLiu/translationCSAPP
课程视频:https://www.bilibili.com/video/av31289365/
这一讲的主题是浮点数。
背景:小数二进制数
二进制小数
转换成十进制的结果为
例子
值 | 表示 |
---|---|
$5\frac 3 4$ | $101.11_2$ |
$2\frac 7 8$ | $10.111_2$ |
$1\frac{7 }{16}$ | $1.0111_2$ |
不难得到如下结果
- 右移(无符号)相当于除以$2$
- 左移(无符号)相当于乘以$2$
- $0.111111 \ldots _2$比$1.0$略小,因为
- $1 / 2+1 / 4+1 / 8+\ldots+1 / 2^{i}+\ldots \rightarrow 1.0$
- 表示为$1.0-\epsilon$
表示数字
利用二进制表示小数有一些限制。
- 限制1
- 有限位只能表示形如$x / 2^{k}$的数
- 例如$\frac 1 3$需要无限位表示:$0.0101010101[01]_{\ldots 2}$
- 限制2
- 表示的范围有限,无法表示非常大或者非常小的数字
IEEE浮点标准:定义
浮点数表示
数值形式:
- 符号位$s$确定数字是负数还是正数
- 尾数$M$为属于范围$1\sim 2-\epsilon$或$0\sim 1-\epsilon$的二进制小数
- 阶码$E$是指数
编码
- 最高位s表示符号位$s$
- 阶码字段exp表示$E$
- 小数字段frac表示$M$
根据阶码字段的不同,浮点数可以分为以下几个部分:
下面分别介绍:
规格化的值
- 当$\text{exp}\neq 000\ldots 0$且$\text{exp}\neq 111\ldots 1$称为规格化的值
- 阶码的值为$E=\exp -\text{bias}$
- 其中$\exp$为exp域的无符号值
- $\text {bias}=2^{k-1}-1$,其中$k$为exp域的比特数
- 小数字段隐式的用$1$作为首位:$M=1 .\text{xxx} \ldots \text{x}_{2}$
- $\text{xxx} \ldots \text{x}$:小数域
- 取最小值当$\text{frac}=000\ldots 0(M=1.0)$
- 取最大值当$\text{frac}=111\ldots 1(M=2.0-\epsilon)$
来看一个具体例子:
浮点数$F=15213.0$
尾数:
阶码:
结果:
非规格化的值
此时
- 当$\text{exp}=000\ldots 0$称为非规格化的值
- 阶码为$E=1-\text {bias }$
- 小数字段的首位为$0$,即$M=0 .\text{xxx} \ldots \text{x}_{2}$
- 例子
- $\exp =000 \ldots 0, \text {frac}=000 \ldots 0$
- 上述两者均表示$0$
- 注意根据符号位的不同有$+0$和$-0$的区别
- $\exp =000 \ldots 0, \text {frac}\neq000 \ldots 0$
- 可以表示接近于$0.0$的数
- $\exp =000 \ldots 0, \text {frac}=000 \ldots 0$
特殊值
- 当$\text{exp}=111\ldots 1$称为特殊值
- 例1:$\exp =111 \ldots 11, \text {frac}=000 \ldots 0$
- 表示$\infty$
- 表示操作溢出,$s=1$表示$-\infty$,$s=0$表示$+ \infty$
- $1.0 / 0.0=-1.0 /-0.0=+\infty, 1.0 /-0.0=-\infty$
- 例2:$\exp =111 \ldots 01, \text {frac}\neq000 \ldots 0$
- Not-a-Number(NaN)
- 表示计算结果无法表达的情形
- 例如$\text{sqrt}(-1),\infty-\infty,\infty \times 0$
可视化:浮点编码
例子和性质
考虑8比特的浮点数表示:
浮点数和对应编码的关系如下:
从上表中不难看出,如果将浮点数的二进制表达视为无符号整数,则上述表达是升序的,这也是IEEE设计这种表达的原因(只考虑正数部分)。
不难发现越接近于$0$的部分浮点数越密集:
IEEE编码的特殊性质
- 浮点数零与整型数零的表达式相同
- 所有比特都为$0$
- (几乎)可以使用无符号整数比较
- 必须首先比较符号位
- 必须考虑$-0=0$
- NaN有问题
- 比其他值大
- 比较的结果是什么?
- 其他部分没问题
- 非规格化 vs 规格化
- 规格化 vs 无穷
舍入,加法,乘法
浮点数运行的基本想法
- $\mathrm{x}+_\mathrm{f} \mathrm{y}=\operatorname{Round}(\mathrm{x}+\mathrm{y})$
- $\mathrm{x}\times_\mathrm{f} \mathrm{y}=\operatorname{Round}(\mathrm{x}\times\mathrm{y})$
- 基本想法
- 首先计算精确结果
- 使它适合所需的精度
- 如果指数太大可能会溢出
- 可能将其舍入为frac
舍入
考虑几种舍入的方法:
浮点数采用的是向偶数舍入。
向偶数舍入
默认舍入模式
- 其他的舍入模式会产生偏差:一组正数之和将一致地被高估或低估
应用于小数位/比特位
当位于中间值时,进行舍入,使得最低有效位为偶数
例子
| 值 | 舍入 | 原因 |
| ————- | —— | ———————————- |
| 7.8949999 | 7.89 | (Less than half way) |
| 7.8950001 | 7.90 | (Greater than half way) |
| 7.8950000 | 7.90 | (Greater than half way) |
| 7.8850000 | 7.88 | (Half way-round down) |
舍入二进制数
二进制小数
- 如果最低有效位为$0$则表示偶数
- 中间值表示为$100\ldots_2$
例子
舍入到小数点后$2$比特
| 值 | 二进制 | 舍入 | 动作 | 舍入后的值 |
| ———————- | —————— | ————- | ———————————- | —————— |
| $2\frac 3 {32}$ | $10.00011_2$ | $10.00_2$ | $(<1 / 2-\text {down})$ | $2$ | | $2\frac 3 {16}$ | $10.00110_2$ | $10.01_2$ | $(>1 / 2-\text{up})$ | $2\frac 14$ |
| $2\frac 7 {8}$ | $10.11100_2$ | $11.00_2$ | $(1 / 2-\text{up})$ | $3$ |
| $2\frac 5 {8}$ | $10.10100_2$ | $10.10_2$ | $(1 / 2-\text{down})$ | $2\frac 1 2$ |
浮点数乘法
- 考虑$(-1)^{s_1} M_1 2^{E_1} \times(-1)^{s_2} M_2 2^{E_2}$
- 精确结果:$(-1)^sM2^E$
- 符号位$s$:$s_1 \text{^} s_2$
- 尾数$M$:$M_1\times M_2$
- 阶码$E$:$E_1+E_2$
- 修正
- 如果$M\ge 2$,右移$M$,增加$E$
- 如果$E$超过范围,则溢出
- 舍入$M$以满足frac的精度
浮点数乘法的数学性质
- 与交换环比较
- 在乘法运算下封闭?是的
- 但可能会产生无穷大或NaN
- 可交换的?是的
- 可结合? 不是
- 四舍五入的溢出和不精确
- $(1 e 20 1 e 20) 1 e-20=\inf , 1 e 20 (1 e 20 1 e-20)=1 e 20$
- $1$是乘法幺元?是的
- 乘法关于加法有分配率吗?不是
- 四舍五入的溢出和不精确性
- $1 e 20 \star(1 e 20-1 e 20)=0.0,1 e 20 1 e 20-1 e 20 1 e 20=\mathrm{NaN}$
- 在乘法运算下封闭?是的
- 单调性
- $a\ge b\Rightarrow a+c\ge b+c$?几乎成立
- 除了无穷大和NaN
- $a\ge b\Rightarrow a+c\ge b+c$?几乎成立
浮点数加法
- 考虑$(-1)^{s_1} M_1 2^{E_1}+(-1)^{s_2} M_2 2^{E_2}$,假设$E_1>E_2$
- 精确结果:$(-1)^sM2^E$
- 符号位$s$,尾数$M$:对齐加法的结果
- 阶码$E$:$E_1$
- 修正
- 如果$M\ge 2$,右移$M$,增加$E$
- 如果$M<1$,左移$M$ $k$个位置,让$E$增加$k$
- 如果$E$超过范围,则溢出
- 舍入$M$以满足frac的精度
浮点数加法的数学性质
- 与阿贝尔群比较
- 在加法运算下封闭?是的
- 但可能会产生无穷大或NaN
- 可交换的?是的
- 可结合? 不是
- 四舍五入的溢出和不精确性
- $(3.14+1e10)-1e10 = 0, 3.14+(1e10-1e10) = 3.14$
- $0$是加法幺元?是的
- 每个元素都有加法逆吗? 除了无穷大和NaN
- 在加法运算下封闭?是的
- 单调性
- $a\ge b\Rightarrow a+c\ge b+c$?几乎成立
- 除了无穷大和NaN
- $a\ge b\Rightarrow a+c\ge b+c$?几乎成立
C中浮点数
- C中有两种精度的浮点数
- float:单精度
- double:双精度
- int,float,double进行转换时,程序改变比特的模式如下
- double/float转换为int
- 截断分数部分
- 向$0$舍入
- 如果超过NaN范围则没有定义:通常转换为$\text{TMin}$
- 例如$1.999$转换为$1$,$-1.999$转换为$-1$,$1e10$转换为$-21483648$
- int/float转换为double
- 因为double的范围更大,所以保留精确值
- int转换为float
- 数字不会溢出,但是可能会产生舍入(float的frac域没有足够的位表示int)
- double转换成float,可能溢出为$+\infty$或$-\infty$,由于精度的问题还会产生舍入
- double/float转换为int
总结
- IEEE浮点具有明确的数学性质
- 用$(-1)^s\times M\times 2^E$表示数
- 与实数运算不同
- 违反结合律/分布率
- 给编译器和数值应用程序带来麻烦
习题
int x = …;
float f = …;
double d = …;
假设d,f不是NaN。
1.
False,因为转换成float会产生舍入。
2.
True,double表示的范围更大。
3.
True,double表示的范围更大。
4.
False,产生溢出或舍入。
5.
True,因为只改变了符号位。
6.
False
7.
True
8.
True,因为单调性
9.
True
10.
False,因为不满足结合律