浮点型有单精度浮点型 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
上面就是一个浮点型存储过程,相反,取值的过程,则反过来。
注:取的过程中,有两个特殊的,当E区的值都为0时,则这个数趋于0;
当E区的值都为1时,则这个数趋于无穷;
以上就是国际标准IEEE(电气和电子工程协会)754规定下浮点型在内存中存取的一个过程,有什么不足之处,望指教。