【C语言】数据的存储_数据类型:浮点型存储

常见的浮点数:

3.1415926

1E10 

浮点型包括:float、double、long double类型

浮点数表示的范围:float.h中定义

 浮点数存储规则:

第二个n和*pFloat在内存中明明是同一个数,但浮点数和整数解读结果差别很大。

要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。

详细解读:

根据国际标准IEEE(电子和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:

(-1)^S*M*2^E

(-1)^S表示符号位,当S=0,V为正数,当S=1,V为负数

M表示有效数字,大于等于1,小于2.

2^E表示指数位

举个栗子:

比如V=5.0,我们先把它转化成二进制即101.0,然后再写成科学计数法的形式即1.01*2^2(第一个2表示是二进制,第二个2表示移两位)所以可以写成(-1)^0*1.01*2^2。

再如V=9.5,我们把它转化为二进制位1001.1(因为最后一个1的权重表示2^-1,即0.5),转化为科学计数法的形式:1.0011*2^3,即(-1)^0*1.0011*2^3。(S=0,M=1.0011,E=3)

又如V=9.6,我们会发现这个数无法转化成二进制,假如说是1001.11,我们会发现小数点后表示0.75,我们发现总是会差一点,从而精度丢失,所以也就是说小数再内存中可能是无法精确保存的,但double类型的精度显然要比float高。

IEEE 754规定:

对于32位的浮点数,最高位的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M。

而对于64位的浮点数,最高位的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。

IEEE 754对有效数字M和指数E有一些特殊的规定:

有效数字M的值是大于等于1,小于2的,所以M可以写成1.xxxxxxxx的形式,其中xxxxxxxx表示小数部分。

IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面xxxxxxxxx的部分。比如保存1.01时,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23,将第一位的1舍去以后,等于可以保存24位有效数字。

相对指数E就比较复杂,首先E是一个无符号整数(unsigned int)这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047,但是我们知道,科学计数法中的E是可以出现负数的,所以IEE 754规定,存入内存E的真实值必须在加上一个中间数,对于8位的E,这个中间数是127;对于11位的E这个中间数是1023.比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001.

#include<stdio.h>
int main()
{
	float f = 5.5;
	//(-1)^0*1.011*2^2
	//S=0  M=1.011  E=2
	//0  2+127=129(真实的E加上中间值)即10000001  01100000000000000000000(M)
	//因此存放的二进制序列为01000000101100000000000000000000
	//写成十六进制即0x40 b0 00 00(小端存放)
	return 0;
}

 

然而,指数E在内存中取出还可以分成三种情况:

E不全为0,或不全为1

这时浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1.

比如:

0.5的二进制形式为0.1,由于规定整数部分必须为1,即小数点向右移一位,则为1.0*2^(-1),其阶码为-1+127=126,表示为

0 01111110 00000000000000000000000

 E全为0

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,

有效数字M不再加上第一位的1,而还原为0.xxxxxxx的小数。这样做是为了表示+0,以及接近0的很小的数字

E为全1

这时,如果有效数字M全为0,表示+无穷大(正负取决于符号位S)

 这些就是关于浮点数的表示规则

举个浮点数存储的例子栗子:

#include<stdio.h>
int main()
{
	int n = 9;
	float* pFloat = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	*pFloat = 9.0;
	printf("n的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	return 0;
}

先看第一部分9的二进制序列为:

00000000000000000000000000001001,我们站在整型的角度去看它,打印出来就是9

而当我们站在浮点型角度

0 00000000 00000000000000000001001

第一个0是符号位表示正数,而E全为0,真实值为-126,表示的数字为(-1)^0*0.00000000000000000001001*2^(-126),是一个无穷小数字

再来看第二部分9.0转化为二进制为:

1001.0=(-1)^0*1.001*2^3

E=3,则存入内存E的真实值为130所以二进制序列为:

0 10000010 00100000000000000000000

站在整型角度0表示正数,所原码、补码、反码相同,这个32的二进制序列转化为十进制,正是1091567616.

 

版权声明:本文为博主作者:你们不要再卷了原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/2401_83283514/article/details/138093103

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2024年5月6日
下一篇 2024年5月6日

相关推荐