标准表示法
为便于软件的移植,浮点数的表示格式应该有统一标准.1985年IEEE(Institute of
Electrical and Electronics
Engineers)提出了IEEE754标准.该标准规定基数为2,阶码E用移码表示,尾数M用原码表示,根据原码的规格化方法,最高数字位总是1,该
标准将这个1缺省存储,使得尾数表示范围比实际存储的一位.实数 的IEEE754标准的浮点数格式为:
具体有三种形式:
表3 IEEE754三种浮点数的格式参数
浮点数
类型 存储位数 偏移值( )
阶码E的取值范围 真值表达式
数符(s) 阶码(E) 尾数(M) 总位数 十六进制 十进制
短实数 1 8 23 32 7FH 127 1~254
长实数 1 11 52 64 3FFH 1023 1~2046
临时实数 1 15 64 80 3FFFH 16383 1~32766
对于阶码为0或为255(2047)的情况,IEEE有特殊的规定,由于篇幅有限,在此不讨论.
在浮点数总位数不变的情况下,其精度值与范围值是矛盾的,因此一般的机器都提供有单、双精度两种格式.表4中列出了IEEE754单精度浮点数的表示范围,对于双精度只需要修改一下偏移值和尾数位数即可.
表4 IEEE754单精度、双精度浮点数范围
典型范围 浮点数代码 真 值
数符(Ms) 阶码(E) 尾数(M)
最大正数
最小正数
绝对值最大的负数
绝对值最小的负数 0
0
1
1 11111110
00000001
11111110
00000001 11………11
00………00
11………11
00………00
标
准浮点数的存储格式与图1(b)相似,只是在尾数中隐含存储着一个1,因此在计算尾数的真值时比一般形式要多一个整数1.对于阶码E的存储形式因为是
127的偏移,所以在计算其移码时与人们熟悉的128偏移不一样,正数的值比用128偏移求得的少1,负数的值多1,为避免计算错误,方便理解,常将E当
成二进制真值进行存储.例如:将数值-0.5按IEEE754单精度格式存储,先将-0.5换成二进制并写成标准形式:-0.510=-0.12=-
1.0×2-12,这里s=1,M为全0,E-127=-1,E=12610=011111102,则存储形式为:
1 01111110 000000000000000000000000=BE00000016
这里不同的下标代表不同的进制.
以32位的float为例, 32位从前向后,1位符号位,8位阶码,23位值码(值码这个词是我生造的。。。)。
1.符号位,表示正反,一个浮点数的相对值只变这一位,不像整数一样还要补码。
2. 阶码,阶码的值有四种,a. 阶码为全1,值码为0,根据符号位,是正无穷,或者负无穷; b. 阶码为全1, 值码不为零,是NaN; c. 阶码不是全1,但不是0,是正常浮点数, 阶码最大为0xfe;d. 阶码为全0,是非规正化数,后面说 c 和 d 的区别。
3. 值码,值码的表示范围,能确定浮点数能表示几位有效数字。c 和 d的区别也在这儿,先说怎么从浮点数的硬件表示计算表达的值。
对 c 来说 val = (1.xxxxxxx)*2^(exp - 127), 从前到后, xxxx是值码的各位,并且是二进制小数的形式 (比如1.1 就是 1 + 2^-1, 1.01 就是 1+ 2^-2); exp是值码. 2^8 = 256, 127差不多是exp可取值集合的中值. (127是对float来说,对double就是1023了,可以推算为什么)
对 d 来说 val = (0.xxxxxx)*2^(-126)。
结论: 一般来说,float的表示范围就是c类的范围,d类被忽略是因为d类的有效数字不能保证,c类能保证在7位左右。
所以,表示范围是 1.0*pow(2, 1-127) ~ 2*pow(2, 0xfe- 127).
(1.1111111111111111111111)
= 2 - 2^(-23)
~= 2