十一.数据的存储(3)

5.浮点型在内存中的存储

先来看几个常见的浮点数

3.1415926

1E10   (1*10^10)

浮点数家族包括:float,double,long double

浮点数的表示范围在float.h中定义,整型的在limits.h中

-- -- -- -- -- -- -- -- -- -- -- -- -- -- --

引例

#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("%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	return 0;
}

运行结果:

n的值为:9
*pFloat的值为:0.000000
1091567616
*pFloat的值为:9.000000

num 和 *pFloat 在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大。要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --

规定

规定1

根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式
  • (-1)^S * M * 2^E
  • (-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数
  • M表示有效数字,大于等于1,小于2    (1≤M<2)
  • 2^E表示指数位,E是阶码

如引例中的9:

十进制:9.0(正)

二进制:1001.0  ——>  1.0010*2^3

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

可以看一下图示

-- -- -- -- -- -- -- -- -- --

规定2

IEEE754规定:对应32为浮点数(float),最高位是符号位S,接着8位是指数E,剩下的32位是有效数字M

 

 

 

-- -- -- -- -- -- -- -- -- --

规定3

IEEE754 对有效数字M和指数E还有一些特别的规定,前面说过,1≤M≤2,即M总可以写成1.xxxxxx的形式,其中xxxxxx为小数部分

因为1总是出现,所以保存时只保存xxxxxx(小数部分),读取时再把1加回去,这样可节省一位有效数字,从而增加精度。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字

-- -- -- -- -- -- -- -- -- --

规定4

关于指数E,它的情况就比较复杂。首先E是一个无符号整数(unsigned int),这意味着如果E为8为,它的取值是0~255(本章第二节讲过);如果E为11位,它的取值是0~2047.但是,我们知道,科学计数法中E是可以出现负数的。所以IEEE754规定,存入内存时E的真实值必须再加上一个中间数(偏移量),对于8位的E(float),这个中间数是127;11位的E(double)则是1023

 所以对于上面这个数的指数位存入内存中的就是10001001

-- -- -- -- -- --

而再我们将E从内存中取出时又可以分为三种情况

1.在E中0和1都有

这时,浮点数的表示规则为,指数E的计算值减去127(或者1023),得到真实值,再将计算出来的有效数字补上以前去掉的1

2.E全为0

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字不再加上以前去掉的1,而是还原成一个0.xxxxxx这样的小数。这样做的原因是为了表示±0、以及接近0的很小的数字

3.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("%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	return 0;
}

9:存入整型,打印整型就是9

0.000000:存入整型,打印浮点型。(十进制)9—>(二进制)0 00000000 000...0001001, 我们可以发现,9转换成二进制它的E全是0(取出时应该用第二种情况的规则)。等于(-1)^0 × 0.000000 00000000000001001×2^(-126)=1.001×2^(-146),由于在打印时计算机只会打印小数点的后6位,所以结果位0.000000

1091567616:存入浮点型,打印整型。首先,浮点数9.0等于二进制的1001.0,即1.001×2^3

那么,第一位S=0,有效数字M=001后面再加200,凑满23

 

 

指数E3+127=130, 即10000010。所以,写成二进制形式,应该是s+E+M,即这个32位的二进制数,还原成十进制,正是 1091567616

9.0:存入浮点型,打印浮点型就是9.000000

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

世长老

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值