二进制浮点数规范化
巡山小妖精
900次浏览
2021年01月17日 16:23
最佳经验
本文由作者推荐
黄花菜汤的做法-网站建设方案书
竭诚为您提供优质文档
/
双击可除
二进制浮点数规范化
篇一:浮点数的二进制表示
浮点数的二进制表示
1.
前几天,我在读一本
c
语言教材,有一道例题:
#include
voidmain(void)
{
intnum=9;/*num
是整型变量,设为
9*/
float*pFloat=/*pFloat
表示
num
的内存地址,但是设< br>为浮点数
*/printf(
的值为:
%dn
显示
num的
整型值
*/
printf(
的值为:
%fn
显示
num
的浮点值
*/
*pFloat=9.0;/*
将
num
的值改为浮点数
*/
printf(
的值为:
%dn
显示
num< br>的整型值
*/
printf(
的值为:
%fn
显示
num
第
1
页
共
19
页
的浮点值
*/
}
运行结果如下:
num
的值为:
9
*pFloat
的值为:
0.000000
num
的值为:
1091567616
*pFloat
的值为:
9.000000
我很惊讶 ,
num
和
*pFloat
在内存中明明是同一个数,
为什么浮点数 和整数的解读结果会差别这么大?
要理解这个结果,一定要搞懂浮点数 在计算机内部的表
示方法。我读了一些资料,下面就是我的笔记。
2.
在讨论浮点数之前,先看一下整数在计算机内部是怎样
表示的。
intnum=9;
上面这条命令,声明了一个整数变量,类型为int
,值
为
9
(二进制写法为
1001
)
。 普通的
32
位计算机,用
4
个字
节表示
int
变量 ,所以
9
就被保存为
00001001
,写成
16
进制就是
0x00000009
。
那么,我们的问题就简化成 :为什么
0x00000009
还原
成浮点数,就成了
0.000000?
3.
第
2
页
共
19
页
根据国际标准
ieee754
,任意一个二进制浮点数
V
可以
表 示成下面的形式:
V=(-1)^s
×
m
×
2^e
(
1
)
(-1)^s
表示符号位,当
s=0
,
V为正数;当
s=1
,
V
为负数。
(
2
)
m
表示有效数字,大于等于
1
,小于
2< br>。
(
3
)
2^e
表示指数位。
举例来说,十进制的
5.0
,写成二进制是
101.0
,相当
于< br>1.01
×
2^2
。那么,按照上面
V
的格式,可以得出s=0
,
m=1.01
,
e=2
。
十进制的
-5.0
,写成二进制是
-101.0
,相当于
-1.01
×
2^2
。那么,
s=1
,
m=1.0 1
,
e=2
。
ieee754
规定 ,
对于
32
位的浮点数,
最高的
1
位是符号
位s
,接着的
8
位是指数
e
,剩下的
23
位为有 效数字
m
。
对于
64
位的浮点数, 最高的
1
位是符号位
s
,接着的
11
位是指数
e< br>,剩下的
52
位为有效数字
m
。
5.
ieee754
对有效数字
m
和指数
e
,还有一些特别规定 。
前面说过,
1
≤
m
至于指数
e
,情况就比较复杂。
首先,e
为一个无符号整数
(
unsignedint
)
。
这 意味着,
如果
e
为
8
位,它的取值范围为
0~255
;如果
e
为
11
位,它
的取值范围为
0~2047
。但是,我们知道,科学计数法中的
e
是可以出现负数的,所以
ieee754规定,
e
的真实值必须再
第
3
页
共
19
页
减去一个中间数,对于
8
位的
e
,这个中间数是
127
;对于
11
位的
e
,这个中间数是
1023
。
比如,
2^10
的
e
是
10
,所以保存成
32
位浮点数时,必
须保存成
10+127=137
, 即
10001001
。然后,指数
e
还可以
再分成三种情况:
(
1
)
e
不全为
0
或不 全为
1
。这时,浮点数就采用上面
的规则表示,即指数
e
的计算值减 去
127
(或
1023
)
,得到
真实值,再将有效数字m
前加上第一位的
1
。
(
2< br>)
e
全为
0
。这时,浮点数的指数
e
等于
1 -127
(或
者
1-1023
)
,有效数字
m
不再 加上第一位的
1
,而是还原为
的小数。这样做是为了表示±
0
,以及接近于
0
的
很小的数字。
(
3
)
e
全为
1
。这时,如果有效数字
m
全为0
,表示±
无穷大(正负取决于符号位
s
)
;如果有效数字m
不全为
0
,
表示这个数不是一个数(
nan
)
。
6.
好了,关于浮点数的表示规则,就说到这里。
下面,让我们回 到一开始的问题:为什么
0x00000009
还原成浮点数,就成了
0.00000 0
?
首先,将
0x00000009
拆分, 得到第一位符号位
s=0
,后
面
8
位的指数
e=00000 000
,最后
23
位的有效数字
m=
。
第
4
页
共
19
页