前言
想要理解浮点数为什么叫浮点数, 浮点是什么意思, 先告诉你它有个兄弟叫定点数
定点数
一个32位计算机想要存储小数, 最简单的方法是什么
把32位分成三部分, 一位表示正负, 8位表示整数部分, 23位表示小数部分
由于小数点固定在了第23位和第24位之间, 这种方式可以称为“定点数”
但小数点固定在哪个位置呢
整数部分小了, 表示的数据范围就很小
整数部分大了, 小数的精度又会降低
所以用定点数表示法, 范围和精度相互矛盾, 并不是一种完美的解决方案
浮点数
那么怎么弥补定点数的短板, 就可以用到类似科学计数法, 利用指数, 可以达到小数点浮动的效果
IEEE 754标准中, 浮点数有单精度(32位)和双精度(64位), 以单精度为例
科学计数法表示为
n
=
(
−
1
)
s
∗
1.
(
m
a
n
t
i
s
s
a
)
∗
2
e
x
p
o
n
e
n
t
n = (-1)^s * 1.(mantissa) * 2 ^{exponent}
n=(−1)s∗1.(mantissa)∗2exponent
那么例如
5.8
5.8
5.8 就可以转换为
1.45
∗
2
2
1.45*2^2
1.45∗22 (原数一直除2, 直到整数部分为1)
注意: 指数也分正负, 此处有一个偏置值
b i a s = 2 k − 1 − 1 bias=2^{k-1}-1 bias=2k−1−1 , k为exponent的位数
单精度浮点数bias则为127, 从0到127 表示负数, 从128到255表示正数
那么
5.8
5.8
5.8 的
e
x
p
o
n
e
n
t
=
127
+
2
exponent=127+2
exponent=127+2
尾数
0.45
0.45
0.45 转化为二进制就是不断地乘2, 取结果的整数部分, 无限循环的话取够23位为止, 此处会有忽略, 所以浮点数不是精确的数值类型
通过上面的过程, 基本了解了浮点数如何表示一般的小数, 那么浮点数怎么表示0呢
规格化和非规格化
指数部分有三种取值:
- 当exponent的二进制位不全为0或1时, 表达的数字是规格化形式, 即一般的小数
- 当exponent的二进制位都为0时, 此时为非规格化, 用来表示一些非常接近0的小数,包括0
此时表达式为
n = ( − 1 ) s ∗ 0. ( m a n t i s s a ) ∗ 2 1 − b i a s n = (-1)^s * 0.(mantissa) * 2^{1-bias} n=(−1)s∗0.(mantissa)∗21−bias
当所有二进制位都为0, 即可表示0.0 - 当exponent的二进制位全为1时, 表示特殊值
当mantissa全为0时, s为0表示正无穷, s为1表示负无穷
当mantissa不全为0, 则表示NaN(Not a Number),不是一个合法实数或无穷,或者该数未经初始化