C语言过程化记录-5

在记录四里写了“数据的存储”里整型部分的知识点。本篇介绍另一数据类型——浮点型。

浮点数是指一种既包含小数又包含整数的数据类型。比如3.14,1e3,1.0e-4 等。

浮点型包括float, double, long double类型。

 浮点型在内存中的存储

为了研究浮点型如何存入,可以引入一个例子。首先观察下列代码:

int main()
{
	int n = 9;
	float* pFloat = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);

	*pFloat = 9.0;
	printf("num的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	return 0;
}

 程序运行后,得到结果如下:

通过观察每行数据是如何得到的,我们可以发现第二行和第三行的打印不太正常——为什么用浮点型输出整型数据得到的是0?为什么用整型输出浮点型数据得到的是一个很大的数?从这里可以展开对于float型数据内存存储的研究。

1. 首先提出计算机内部分析处理浮点数的方式,任意一个二进制浮点数V可以表示成下面的形式:

(-1)^S * M * 2^E,其中

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

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

2^E表示指数位。

用一个例子来说明,

  • 一个十进制数7.0,写成二进制是111,转换为浮点数表示就是 (-1)^0*1.11*2^3
  • 一个十进制数-7.0,写成二进制是-111,转换为浮点数表示就是 (-1)^1*1.11*2^3

 2. 理解了读取方式后,就可以进一步观察单精度浮点型float和双精度浮点型double的对于二进制浮点数具体存放形式(后文图源皆来自:比特课件):

  注意阅读红色标出部分。理解上文后,以5.5为例进行理论实践 ,分析其在内存中是如何存储的。

    float f = 5.5f;//5.5后面的f是用来说明7.7是单精度浮点型数字
	//5.5的二进制形式:101.1
	//其中 s = 0, E = 2, M = 1.011
	//放进内存存储后:s = 0, E = 2 + 127, M = 011
	//转换为二进制  :0      1000 0001    011 00000000000000000000(M填在前面,后面补0)
	//0100 0000 1011 0000 0000 0000 0000 0000
	//转换为十六进制:40 b0 00 00
	return 0;

最后运行程序,打开内存窗口搜索f 的地址,得到结果如上图(使用小端存储)。

3. 最后再介绍E取值时的三种情况。

这是正常情况,

 这种情况,由于指数表示的数很小,最终表示趋近于0的数字,注意此时M不会再加上个位的1

这种情况发生需要两个条件:E全为1,M全为0

理解了以上3点后,再回到最开始研究的例子,我们可以开始一个个分析:

 第一行打印,int数据进行int输出,结果必然为9;

第二行打印,int数据进行float输出,这里就要联系上32位二进制的读取方式转换。

  1. 已知int数据9的二进制为0000 0000 0000 0000 0000 0000 0000 1001;当它作为float数据被读取时,分析如下:s = 0, E = 0, M = 000 0000 0000 0000 0000 1001;
  2. 其中,由于E全为0,则读出真实值时,M前面不再补上个位的1,即真实值为0.000 0000 0000 0000 0000 1001 * 2 ^ ( 1-127 ) ,这个数已经很趋近于0了,又因为float最多只能打印到小数点后6位,因此最终打印结果为 “0.000000”。

第三行打印,float数据进行int输出,和上一行在分析步骤上正好对换了。

  1. 这里我们首先要将32位二进制用float的形式写出,再将其用int的读取形式打印出来。9.0以float形式存入,S = 0, E = 3, M = 001, 所以它的二进制为:0100 0001 0001 0000 0000 0000 0000 0000;
  2. 然后再用int的方式打印。上面二进制转为十进制为2^31+2^25+2^21 = 1,091,567,616。即最终屏幕上的输出结果。

 第四行打印,float数据进行float输出,结果必然为9.000000。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值