IEEE754 浮点数表示
IEEE754 浮点数标准是当今在计算机中使用最为普遍的浮点数表示方法。这篇文章将对IEEE浮点数表示方法给出一个简短的介绍。
1. 什么是浮点数
计算机中小数的小数点并不是用某个数字表示的,而是用隐含的小数点的位置来表示的。根据小数点的位置是否固定,又可以分为定点表示和浮点表示。浮点数顾名思义就是小数点不固定,是浮动的,要处理的数既有整数部分又有小数部分。在计算机中一般采用浮点表示方法。
2. 存储结构
IEEE浮点数由三个基本的部分组成:符号(Sign)、指数(Exponent)和尾数(mantissa)。其中尾数由分数(fraction)和隐含的前导数字(leading digit)组成。指数的基数为2。下面给出单精度和双精度浮点数的存储结构。
| Sign | Exponent | Fraction | Bias |
Single Precision | 1[31] | 8[30-23] | 23[22-0] | 127 |
Double Precision | 1[63] | 11[62-52] | 52[52-0] | 1023 |
2.1. 符号位
0: 正数 1: 负数
2.2. 指数
指数应该既能表示正数也能表示负数。为了实现找个目的,存储的指数在实际的指数上被加上一个偏差。对于IEEE单精度数而言,这个偏差是127(双精度为1023)。
2.3. 尾数
尾数位的多少反映了数的精确程度。它由一位隐含的前导位和分数位组成。前导位为1,不需要显示表示出来。这样,尾数实际上由24位组成。
3. 浮点数表示范围
正浮点数的表示范围可以被分成规范化的数和非规范化的数(只用了一部分分数的精度)。
| Denormalized | Normalized | Approximate Decimal |
Single Precision | ± 2-149 to ( 1-2 -23 )×2-126 | ± 2-126 to ( 2-2 -23 )×2127 | ± ~10-44.85 to ~1038.53 |
Double Precision | ±2-1074 to ( 1-2 -52 )×2-1022 | ± 2-1022 to ( 2-2 -52 )×21023 | ± ~10-323.3 to ~10308.3 |
有五个不同的数值范围单精度数不能表示。
¨ 小于-( 2-2 -23 ) × 2127的负数:(negative overflow)
用规范化形式表示的浮点数最小负数为:-( 2-2 -23 ) × 2127,其内存表示为:
1 11111110 11111111111111111111111
¨ 大于-2-149的负数:(negative underflow)
用非规范化形式表示的浮点数最大负数为:-2-149,其内存表示为:
1 00000000 00000000000000000000001
¨ 零:0最为一种特殊值进行处理
¨ 小于2-149的负数:(positive underflow)
用非规范化形式表示的浮点数的最小正数为:2-149 ,其内存表示为:
0 00000000 00000000000000000000001
¨ 大于( 2-2 -23 ) × 2127的正数:(positive overflow)
用规范化的形式表示的浮点数的最大正数为:-( 2-2 -23 ) × 2127,其内存表示为:
1 11111101 11111111111111111111111
上溢指的是所要表示的数值太大以至于不能被表示,下溢不太严重,因为它只表示精度的损失。可以通过接近零得到保证。
这样IEEE浮点数所能表示的有效范围如下表:
| Binary | Decimal |
Single | ± ( 2-2 -23 ) × 2127 | ~ ± 1038.53 |
Double | ± ( 2-2 -52 ) × 21023 | ~ ± 10308.25 |
4. 特殊值
IEEE保留了指数域全零和全1表示不同的特殊值。
¨ 零(Zero)
由于前导1的原因,0不能以正常的形式在浮点数中表示出来,必须以特殊值的形式对待。零是一个指数域和尾数域全零的特殊值,有+0和-0之分,但他们相比较是相等的。
¨ 非规范化
如果指数全零,而尾数不为零,那么这就是一个非规范化的数,它并不假定前导1的存在。
¨ 无穷
无穷是通过指数域全1,尾数域全0表示的。符号位区分正无穷和负无穷。
¨ 不是一个数(Not A Number)
NaN用于表示一个并不是真实数字的值。NaN是通过指数域全1,尾数域不为零表示的。由两种NaN:QNaN(Quiet NaN)和SNaN(Signalling NaN)。
关于这两种NaN的区别,可以参考下面的英文解释:
A QNaN is a NaN with the most significant fraction bit set. QNaN's propagate freely through most arithmetic operations. These values pop out of an operation when the result is not mathematically defined.
An SNaN is a NaN with the most significant fraction bit clear. It is used to signal an exception when used in operations. SNaN's can be handy to assign to uninitialized variables to trap premature usage.
Semantically, QNaN's denote indeterminate operations, while SNaN's denote invalid operations.
5. 特殊操作
特殊值上的操作在IEEE中被良好的定义。简单的情况是任意的包含NaN的操作都产生NaN。其他操作如下:
Operation | Result |
n ÷ ±Infinity | 0 |
±Infinity × ±Infinity | ±Infinity |
±nonzero ÷ 0 | ±Infinity |
Infinity + Infinity | Infinity |
±0 ÷ ±0 | NaN |
Infinity – Infinity | NaN |
±Infinity ÷ ±Infinity | NaN |
±Infinity × 0 | NaN |
6. 总结
下面给出了表示一种表示方法对应的值:(b = bias)
Sign | Exponent(e) | Fraction(f) | Value |
0 | 00..00 | 00..00 | +0 |
0 | 00..00 | 00..01 11..11 | 正非规范化数: 0.f × 2(-b+1) |
0 | 00..01 11..11 | 00..00 11..11 | 正规范化数: 1.f × 2(e-b) |
0 | 11..11 | 00..00 | +Infinity |
0/1 | 11..11 | 00..01 01..11 | SNaN |
0/1 | 11..11 | 10..00 11..11 | QNaN |
1 | 00..00 | 00..00 | -0 |
1 | 00..00 | 00..01 11..11 | 负非规范化数: -0.f × 2(-b+1) |
1 | 00..01 11..10 | 00..00 11..11 | 负非规范化数: 1.f × 2(e-b) |
1 | 11..11 | 00..00 | -Infinity |