C语言中浮点型存储方式

70 阅读2分钟

浮点型有单精度浮点型 float 和双精度浮点型 double,下面一起探讨一下浮点型数据在内存中的存储和读取。

下面内容根据国际标准IEEE(电气和电子工程协会)754规定,也就是说使用这个规定的编译器,都会按照这个方式存储。

为了方便了解,这里先对浮点型存储简单做个总结。(这里有些词只是为了方便了解,并不是官方词汇)

十进制 - 二进制 - 科学计数法 - 代公式 - 代区间 - 十六进制

十进制:

例如 float num = 10.5 或者 double num = 10.5;
其中 10.5 就是十进制方式表示的数。

二进制:

将上面的十进制数写成二进制方式,则为1010.1。小数点后的1表示5,1*2^(-1)=0.5;

科学计数法:

将上面的二进制数改写为科学计数法,则为1.0101 * 2^3。
注:该数需要为1-2范围内。

带公式:

这里先要介绍一个国际标准IEEE(电气和电子工程协会)754规定的公式:
公式:(-1)^S*M*2^E
S:(-1)^s,如果这个浮点数是正数,则S为0;否则为1。
M:M表示科学计数法步骤中*前面的数,如上步骤的1.0101。
E:E表示科学计数法步骤中2的次方数,如上步骤的3。
通过上面的公式就能确定 S M E 三个值了。

代区间:

这里先要了解一下浮点型的一个存储模型。浮点型在存储时,会开辟一块空间,分为SEM区,如下:

float: 
 - ------------ -------------------
|S|     E      |        M          |
 - ------------ -------------------
 1      8               23
 
double- ------------ -------------------
|S|     E      |        M          |
 - ------------ -------------------
 1      11              52
 
 那这几块区间,该如何存放呢?这就用到了上一步骤的三个值了。
 S区:对应的S值。
 E区:(根据单双精度确定)
     float:E值 + 127,转二进制存储。
     double:E值 + 1023,转二进制存储。
 M区:M值小数点后的数,如上步骤的0101,然后补0补完整即可。

十六进制:

 通过上一步骤,其实就可以确定由0、1组成的二进制数据了,然后转成16进制数据就是内存中存储的数据。

代码演示:

float num_one = 10.5; -- 41 28 00 00 00 00 00 00
double num_two = 10.5; -- 40 25 00 00 00 00 00 00

image.png

image.png

上面就是一个浮点型存储过程,相反,取值的过程,则反过来。

注:取的过程中,有两个特殊的,当E区的值都为0时,则这个数趋于0;
    当E区的值都为1时,则这个数趋于无穷;

以上就是国际标准IEEE(电气和电子工程协会)754规定下浮点型在内存中存取的一个过程,有什么不足之处,望指教。