浮点数
早期的计算机使用定点数来表示实数,由于定点数的小数点位置固定,而计算机字长有限,定点数无法表示很大和很小的实数,因此而在计算机科学中有了对于实数近似值数值的表示法——浮点数。这种表示法类似于十进制中的科学计数法——它的优点是数的数量级、精确度以及数值都非常准确,浮点数表示其基数为 2 2 ,因此一个浮点数 由两个数 m m 和 来表示: a=m×be a = m × b e ,其中 b b 表示基数, 称为尾数。下面对浮点数在计算机中的表示详细介绍。
1.1 浮点数在计算机中的表示
浮点数可以这样表示[1]:
也就是说浮点数的实际值等于,符号值乘以指数偏移值,再乘以分数值。
我们知道当前绝大多数计算机(据说有过三进制计算机[7])的数据都是二进制编码(0 和 1),在计算机中,二进制的浮点数按照以上公式在一定字长内(单精度浮点数32位,双精度浮点数64位)分别存储“符号位(sign bit)”,“指数部分”——次高有效的 e 个比特,以及“有效数(significand)”的小数部分——非规约数(稍后介绍)整数部分为 0,其他整数部分一律为 1。存储形式如下图所示:
(图片引用自[1])
1.1.1 指数偏移值
这里着重介绍关于“指数部分”的偏移量,IEEE754 中规定,单精度浮点数的指数域是 8 个比特,因此它的指数偏移值为 28−1−1=127 2 8 − 1 − 1 = 127 ,64 位双精度浮点数的值数域是 11 个比特,它的指数偏移值为 211−1−1=1023 2 11 − 1 − 1 = 1023 。为什么要指数编码时需要加上一个偏移值?
我们知道,在 10 进制的科学计数法中,指数可以是负数,而计算机存储浮点数的“指数部分”又是一个无符号的整数,因此,在 IEEE754 标准规定,exponent 必须减去一个偏移值而得到真实的“指数值”。
为什么单精度浮点数指数偏移值是 127,双精度浮点数指数偏移值是 1023 呢? IEEE754 标准规定了几个特殊值[1]:
- 如果指数是 0 并且尾数的小数部分是 0,这个数是 ±0(和符号位有关)。
- 如果指数 =2e−1 = 2 e − 1 并且尾数的小数部分是 0,这个数是 ±∞(同样和符号位有关)。
- 如果指数 =2e−1 = 2 e − 1 并且尾数的小数部分非 0,这个数表示为不是一个数 NaN。
(注意,这里所说的指数是指编码后的指数值(即阶码),而非指数真值,务必了解清楚。)
[8]这就意味着,单精度浮点数的 8 位阶码(即移码表示的指数部分)除特殊值外所表示范围为 (1,254) ( 1 , 254 ) ,我们知道 8 位有符号数的补码取值范围是 (−128,+127), ( − 128 , + 127 ) , 假设偏移值是 +128,在表示真值 +127 时阶码为 1111 1111,显然,根据 IEEE754 标准,255 是保留数值,偏移值是 +128 表达 +127时产生了上溢。与此同时,偏移值为 +127,在表达 -127 时,阶码为 0000 0000,同样依据 IEEE754 标准,0 也是保留数值,于是产生了下溢(更无法表达 -128 真值),因此阶码真值去掉 -127 和 -128,其取值范围为 (−126,+127)