浮点数的表示思想是基于科学计数法的。例如:1234.5用科学计数法可表示为 1.2345 × 1 0 3 1.2345 \times 10^3 1.2345×103,其中1.2345称为尾数(mantissa),3称为指数或阶(exponent),10称为基数(radix)。在已知进制的情况下,只需要记录尾数和指数即可表示这个浮点数。
同理,在计算机中浮点数表示以2为基数,只需记录尾数和指数即可。例如: 33.25 = ( 100001.01 ) 2 × 2 0 = ( 0.10000101 ) 2 × 2 6 33.25=(100001.01)_2 \times 2^0 =(0.10000101)_2 \times 2^{6} 33.25=(100001.01)2×20=(0.10000101)2×26,在计算机中,只需要记录0.10000101和6即可。
为了在计算机中表示一个浮点数,我们需要表示其尾数和指数。指数使用阶码(移码)来表示,尾数表达均以0.1开头,因此只存储0.1后的数字,这样可以增加表示的范围。例如在32位浮点数中,用8位移码(bias= 2 8 − 1 = 128 2^{8-1}=128 28−1=128)表示指数,则 33.25 = ( 0.10000101 ) 2 × 2 6 33.25 = (0.10000101)_{2} \times 2^{6} 33.25=(0.10000101)2×26中指数可存储为 6 + 128 = 134 = ( 10000110 ) 2 6+128=134=(10000110)_2 6+128=134=(10000110)2,的尾数部分存储为 ( 00001010000000000000000 ) 2 (00001010000000000000000)_2 (00001010000000000000000)2。
| 0(符号位) | 1~8(阶) | 9~31(尾数) |
|---|---|---|
| 0 | 10000110 | 00001010000000000000000 |
上述存储模型中移码范围 [ ( 00000000 ) 2 , ( 11111111 ) 2 ] [(00000000)_2,(11111111)_2] [(00000000)2,(11111111)2],实际表示范围为[-128,127]。尾数的表示范围 [ ( 0.10...0 ) 2 , ( 0.11...1 ) 2 ] [(0.10...0)_2,(0.11...1)_2] [(0.10...0)2,(0.11...1)2],即 [ 2 − 1 , 2 0 − 2 − 24 ] [2^{-1},2^0-2^{-24}] [2−1,20−2−24]。所以该模型能表达的最大正数0.11…1 × 2 11...1 = ( 1 − 2 − 24 ) × 2 127 \times 2^{11...1}=(1-2^{-24}) \times 2^{127} ×211...1=(1−2−24)×2127,最小正数0.10…0 × 2 00...0 = 1 2 × 2 − 128 = 2 − 129 \times 2^{00...0}=\frac{1}{2} \times 2^{-128}=2^{-129} ×200...0=21×2−128=2−129。

浮点数的范围比定点数的范围大,但是同样位数能编码的数个数相同,因此浮点数表达的数之间稀疏且不均匀。阶数决定了浮点数的表达范围,尾数决定了浮点数的而表达精度。
以32位浮点数为例,在 [ 2 1 , 2 2 ] [2^{1},2^{2}] [21,22]和 [ 2 2 , 2 3 ] [2^{2},2^{3}] [22,23]之间数的个数相同,都为 2 23 2^{23} 223个(由尾数的可能情况确定),但是两者的区间长度分别为2和4,所以数字在 [ 2 1 , 2 2 ] [2^{1},2^{2}] [21,22]的分步比在 [ 2 2 , 2 3 ] [2^{2},2^{3}] [22,23]的分步密集。推广可知:越靠近上溢区,数字分步越稀疏。
浮点数表达个数有限,部分实数可以编码表示,其他不能编码表示的实数则用最近的可表达数来代替表示。例如:
#include <iostream>
using namespace std;
int main()
{
float num;
cout.setf(ios::fixed,ios::floatfield);
while(1)
{
cout<<"input:";
cin>>num;
cout<<num<<endl;
}
return 0;
}
运行结果如下:
input:61.419997
61.419998
input:61.419998
61.419998
input:61.419999
61.419998
input:61.42
61.419998
input:61.420001
61.420002
由于61.419998和61.420002是两个可表达数,当输入的数据是一个不可表达数时,机器将其转化为最邻近的可表达数。
但是同一个数可以用多种形式表达,例如 33.25 = ( 0.10000101 ) 2 × 2 6 = ( 1.0000101 ) 2 × 2 5 = ⋅ ⋅ ⋅ 33.25 = (0.10000101)_2 \times 2^6 = (1.0000101)_2 \times 2^5=··· 33.25=(0.10000101)2×26=(1.0000101)2×25=⋅⋅⋅这样不利于数据的传输和程序的移植,因此出现了IEEE 754标准。IEEE 754规定的规格化数形如:+/- ( 1. X X X X X X X ) 2 × 2 E (1.XXXXXXX)_2 \times 2^{E} (1.XXXXXXX)2×2E,其中尾数的1可不存储。IEEE 754规定了单精度浮点数(32 bit)和双精度浮点数(64 bit):
1.单精度浮点数
- 存储模型
| S | Exponent | Significand |
|---|---|---|
| 0 | 1~8 | 9~31 |
| 1 bit | 8 bit | 23 bit |
- 阶 [ ( 00000001 ) 2 , ( 11111110 ) 2 ] [(00000001)_2,(11111110)_2] [(00000001)2,(11111110)2]即[-126,127];bias=127
- 尾数 最高位总为1,可以隐含表示。存储23位,可表示24位的定点小数。
- 真值: ( − 1 ) S × ( 1 + S i g n i f i c a n d ) × 2 E x p o n e n t − 127 (-1)^{S} \times (1+Significand) \times 2^{Exponent-127} (−1)S×(1+Significand)×2Exponent−127
- 规格化数表达范围:
最小正数: ( 1.00...00 ) 2 × 2 00..01 = 2 − 126 (1.00...00)_2 \times 2^{00..01}=2^{-126} (1.00...00)2×200..01=2−126
最大正数: ( 1.11...1 ) 2 × 2 11...10 = ( 2 − 2 − 23 ) × 2 127 = ( 1 − 2 − 24 ) × 2 128 (1.11...1)_2 \times 2^{11...10}=(2-2^{-23}) \times 2^{127}=(1-2^{-24}) \times 2^{128} (1.11...1)2×211...10=(2−2−23)×2127=(1−2−24)×2128
因此,规范化数的表达范围 [ − ( 1 − 2 − 24 ) × 2 128 , − 2 − 126 ] ∪ [ 2 − 126 , ( 1 − 2 − 24 ) × 2 128 ] [-(1-2^{-24}) \times 2^{128},-2^{-126}]\cup[2^{-126},(1-2^{-24}) \times 2^{128}] [−(1−2−24)×2128,−2−126]∪[2−126,(1−2−24)×2128]
例1: 已知float型变量x的机器数为0xBEE00000,求x的值。
0xBEE00000= ( 1011 1110 1110 0000 0000 0000 0000 0000 ) 2 (1011 \ 1110 \ 1110 \ 0000 \ 0000 \ 0000 \ 0000 \ 0000)_2 (1011 1110 1110 0000 0000 0000 0000 0000)2
| 1 | 01111101(125) | 11000000000000000000000 |
|---|
真值为 ( − 1 ) 1 × ( 1 + 2 − 1 + 2 − 2 ) × 2 − 2 = − 1.75 × 2 − 2 = − 0.4375 (-1)^1 \times (1+2^{-1}+2^{-2}) \times 2^{-2}=-1.75 \times 2^{-2}=-0.4375 (−1)1×(1+2−1+2−2)×2−2=−1.75×2−2=−0.4375
步骤:
- 1.在二进制表达式中提取表达阶和尾数的部分;
- 2.利用公式分别求出阶和尾数的十进制数;
例2: 已知float型变量x的值为-12.75,求x的机器数。
− 12.75 = − 1100.11 B = − 1.10011 B × 2 3 -12.75=-1100.11B=-1.10011B \times 2^{3} −12.75=−1100.11B=−1.10011B×23
阶 E = 3 + 127 = 130 = ( 10000010 ) 2 E=3+127=130=(10000010)_2 E=3+127=130=(10000010)2
尾数 S i g n i f i c a n d = ( 100110...0 ) 2 Significand=(100110...0)_2 Significand=(100110...0)2
| 1 | 10000010 | 10011000000000000000000 |
|---|
所以机器数为11000001010011000000000000000000
步骤:
- 1.写出浮点数的二进制表达式;
- 2.转化为规格化形式;
- 3.分别求出阶和尾数的表示;
2.双精度浮点数
- 存储模型
| S | Exponent | Significand |
|---|---|---|
| 0 | 1~11 | 12~63 |
| 1 bit | 11 bit | 52 bit |
- 阶 [ ( 00000000001 ) 2 , ( 11111111110 ) 2 ] [(00000000001)_2,(11111111110)_2] [(00000000001)2,(11111111110)2]即[-1022,1023];bias=1023
- 尾数 最高位总为1,可以隐含表示。存储52位,可表示53位的定点小数。
- 真值: ( − 1 ) S × ( 1 + S i g n i f i c a n d ) × 2 E x p o n e n t − 1023 (-1)^{S} \times (1+Significand) \times 2^{Exponent-1023} (−1)S×(1+Significand)×2Exponent−1023
- 规格化数表达范围:
最小正数: ( 1.00...00 ) 2 × 2 00..01 = 2 − 1022 (1.00...00)_2 \times 2^{00..01}=2^{-1022} (1.00...00)2×200..01=2−1022
最大正数: ( 1.11...1 ) 2 × 2 11...10 = ( 2 − 2 − 52 ) × 2 1023 = ( 1 − 2 − 53 ) × 2 1024 (1.11...1)_2 \times 2^{11...10}=(2-2^{-52}) \times 2^{1023}=(1-2^{-53}) \times 2^{1024} (1.11...1)2×211...10=(2−2−52)×21023=(1−2−53)×21024
因此,规格化数的表达范围 [ − ( 1 − 2 − 53 ) × 2 1024 , − 2 − 1022 ] ∪ [ 2 − 1022 , ( 1 − 2 − 53 ) × 2 1024 ] [-(1-2^{-53}) \times 2^{1024},-2^{-1022}]\cup[2^{-1022},(1-2^{-53}) \times 2^{1024}] [−(1−2−53)×21024,−2−1022]∪[2−1022,(1−2−53)×21024]
除上述的规格化数外,浮点数还可以表示一些特殊的约定值及非规格化数。
以float型为例:
| Signed | Exponent | Significand | Value |
|---|---|---|---|
| X | 0 | 0 | +/- 0 |
| X | 0 | nonzero | Denorms |
| X | 1-254 | XX...X | Norms |
| X | 255 | 0 | +/- Infinity |
| X | 255 | nonzero | NaN |
- 0的表示:阶和尾数全为0时表示真值0.
+0: 0 00000000 00000000000000000000000 0 \ 00000000 \ 00000000000000000000000 0 00000000 00000000000000000000000
-0: 1 00000000 00000000000000000000000 1 \ 00000000 \ 00000000000000000000000 1 00000000 00000000000000000000000
- + / − ∞ +/- \infty +/−∞的表示:阶全为1,尾数全为0
+ ∞ : 0 11111111 00000000000000000000000 + \infty : 0 \ 11111111 \ 00000000000000000000000 +∞:0 11111111 00000000000000000000000
− ∞ : 1 11111111 00000000000000000000000 -\infty : 1 \ 11111111 \ 00000000000000000000000 −∞:1 11111111 00000000000000000000000
例如: 1.0 0 = + ∞ \frac{1.0}{0}=+\infty 01.0=+∞ − 1.0 0 = − ∞ \frac{-1.0}{0}=-\infty 0−1.0=−∞ 1 + ( + ∞ ) = + ∞ 1+(+\infty)=+\infty 1+(+∞)=+∞ 1 + ( − ∞ ) = − ∞ 1+(-\infty)=-\infty 1+(−∞)=−∞ + ∞ + ( + ∞ ) = + ∞ +\infty+(+\infty)=+\infty +∞+(+∞)=+∞ − ∞ − ( + ∞ ) = − ∞ -\infty-(+\infty)=-\infty −∞−(+∞)=−∞
- NaN(Not a Number)的表示:阶全为1,尾数不全为0
例如: − 4.0 = N a N \sqrt{-4.0}=NaN −4.0=NaN 0 0 = N a N \frac{0}{0}=NaN 00=NaN ∞ ∞ = N a N \frac{\infty}{\infty}=NaN ∞∞=NaN + ∞ − ( + ∞ ) = N a N +\infty-(+\infty)=NaN +∞−(+∞)=NaN + ∞ + ( − ∞ ) = N a N +\infty+(-\infty)=NaN +∞+(−∞)=NaN
- 非规格化数(Denorms)的表示:阶全为0,尾数不全为0
形式: ( − 1 ) S × 0. X X . . . X × 2 − 126 (-1)^{S} \times 0.XX...X \times 2^{-126} (−1)S×0.XX...X×2−126
范围: [ − ( 1 − 2 − 23 ) × 2 − 126 , 0 ) ∪ ( 0 , ( 1 − 2 − 23 ) × 2 − 126 ] [-(1-2^{-23})\times 2^{-126},0)\cup(0,(1-2^{-23})\times 2^{-126}] [−(1−2−23)×2−126,0)∪(0,(1−2−23)×2−126] 位于下溢区。
更多内容欢迎参观我的个人站
本文详细介绍了浮点数在计算机中的表示方式,基于科学计数法,通过尾数和指数来存储。讲解了32位浮点数的存储模型,包括阶码和尾数的表示,探讨了浮点数表示的范围和精度。还提到了浮点数的不均匀性和稀疏性,并阐述了IEEE 754标准对于浮点数规范化的规定,包括单精度和双精度浮点数的存储细节,以及特殊值如0、无穷和NaN的表示。
2528

被折叠的 条评论
为什么被折叠?



