C/C++浮点数在内存中的存储方式

时间:2022-07-24 18:59:19

一、内存表示

任何数据在内存中都是以二进制的形式存储的,浮点数的表示是把一个数的有效数字和数的范围在计算机的一个存储单元中分别予以表示,数的小数点位置随比例因子的不同而在一定范围内*浮动。如下图是32位和64位浮点数的表示方法:

C/C++浮点数在内存中的存储方式       C/C++浮点数在内存中的存储方式

在介绍浮点数的存储方式之前我们先介绍下阶码和尾数。

阶码:表达指数部分,用整数形式表示,指明小数点在数据中的位置,决定浮点数的表示范围。

尾数:用定点小数表示,给出有效数字的位数决定了浮点数的表示精度。

理论上,一个十进制数N可以写成N=10e×M,一个R进制数N可以写成N=Re×M,(M 尾数,e 指数,R 基数)例如:156.78=15.678×101=1.5678×102= 0.15678×103=RE×M,那么计算机中究竟采用哪种数据形式呢?

对于二进制数
1011.1101 =0.10111101 ×2+4

= 10.111101 ×2+2

= 1.0111101 ×2+3 (规格化表示法)

= 1.0111101 ×2+11 (11表示二进制的3)(规格化表示法)

=RE×M

根据IEEE754标准,规格化表示原则如下。

1、尾数最高有效位为1,隐藏,并且隐藏在小数点的左边(即:1≤M<2)

2、32位单精度浮点数规格化表示x=(-1)s×(1.M)×2E-127

   e=E-127(E=e+127)

3、64位双精度浮点数规格化表示x=(-1)s ×(1.M)×2E-1023

   e=E-1023(E=e+1023)

指数真值e 用偏移码形式表示为阶码E。

例1:浮点机器数(41360000)16,求真值。

①十六进制数展开成二进制数

0 100 0001 0011 0110 0000 0000 0000 0000

S(1位) 阶码E(8位)  尾数M(23位)

②指数e=阶码-127 =1000 0010-01111111=00000011=(3)10

③包括隐藏位1的尾数1.M =1.011011

④X=(-1)s×1.M×2e=+(1.011011)×23=+1011.011=(11.375)10

例2:真值20.59375,求32位单精度浮点数。

①分别将整数和分数部分转换成二进制数。

20.59375=10100.10011

②移动小数点,使其在第1、2位之间。

10100.10011=1.010010011×24

e=4

S=0

E=4+127=131=10000011

M=010010011

③得到32位浮点数的二进制存储格式为:

01000001101001001100000000000000=(41A4C000)16

二、表示范围

32位单精度浮点数表示范围:

E=1(0000 0001)~254(1111 1110) E全为1是用来通知异常情况。

e=-126~+127

表达的数据范围(绝对值):

最小值:e=-126,M=0(1.M=1)

十进制表达:2-126≈1.18×10-38

最大值:e=127,M=11…1(23个1)

1.M=1.11…1(23个1)=2-2-23

十进制表达:(2-2-23)×2127≈2×2127≈3.40×1038

64位单精度浮点数表示范围:

E=1~2046  E全为1是用来通知异常情况。

e=-1022~+1023

表达的数据范围(绝对值):

最小值:e=-1022,M=0(1.M=1)

十进制表达:2-1022≈2.23×10-308

最大值:e=1023,M=11…1(52个1)

1.M=1.11…1 (52个1)=2-2-52

十进制表达:(2-2-52)×21023≈ 2×21023≈1.79×10308