前言
本节给大家带来的内容是浮点数在内存中的存储,该内容的考察和考试的涉及频率很低,基本上不会涉及,可以适当的了解,提升C语言的内功,也可以不作任何了解
浮点数相关
浮点数在程序中的使用频率较高,常见的浮点数类型有:float、double、long double(其中float类型占用4个字节,double类型占用8个字节,long double类型占用8或者12或者16个字节,long double类型使用的频率较低)其中float类型的数据要在末尾处加f,%f用来打印float类型和double类型,%lf用来打印long double类型,默认打印小数点后六位,如图所示:
浮点数在内存中的存储
我们通过引入一个很经典的例题来进入浮点数的学习:
我们运行程序,得到一个很令人意外的结果:当n为9的时候,将n存入一个float类型的指针并且解引用时发现得到的数据并不为9,而是0。而当解引用*pFloat将其数据更改为9.0时,发现n的值变成了一个很大的数,这种现象间接的证明了,浮点数和整数在内存中的存储方式是不同的。那么,我们来逐一分析这种现象出现的原因
我们通过查阅网络上的资料可以知道,根据国际标准IEEE(电⽓和电⼦⼯程协会)754,规定任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:
V = (−1)^S*M*2E
其中(-1^S 表⽰符号位,当S=0,V为正数;当S=1,V为负数
M 表⽰有效数字,M是⼤于等于1,⼩于2的数
2E 表⽰指数位
举例来说:⼗进制的6.0,写成⼆进制是110,相当于1.10*2^2
同时IEEE 754规定:
对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M
对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M
S | E | E | E | E | E | E | E | E | M | M | M | M | M | M | M | M | M | M | M | M | M | M | M | ... |
此为32位浮点数的存储模式
S | E | E | E | E | E | E | E | E | E | E | E | M | M | M | M | M | M | M | M | M | M | M | M | ... |
此为64位浮点数的存储模式
浮点数存的过程
因为1≤M<2,也就是说,M可以写成 1.xxxxxx 的形式,其中 xxxxxx 表⽰⼩数部分。
IEEE 754规定,在计算机内部保存M时,默认这个数的第⼀位总是1,因此可以被舍去,只保存后⾯的 xxxxxx部分,以32位的浮点数为例,这样就可以保存24位有效数字,比原来多一位
对于指数E而言,情况相对来说复杂很多:因为E为一个无符号的整数,在32位中,E有8位,则它的取值范围是0-255;而在64位中,E有11位,则它的取值范围是0-2047。
但是科学计数法中的E是可以出现负数的,所以根据IEEE 754规定,存⼊内存时E的真实值必须再加上⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023
在32位中,2^14的E是14,则E的真实值应该为 14 + 127 = 141 ,转化为二进制为 10001101
浮点数取的过程
我们知道了浮点数存的过程,那么浮点数取的过程就很好解释了,就将存的顺序反向进行,指数E的计算值减去127(或1023),得到真实值
两个特殊情况
1.E全为0
这时,浮点数的指数E等于1-127(或者1-1023),此时该数是一个极其小的数字,这样做是为了表⽰±0
2.E全为1
这时,浮点数的指数E等于255(或者2047),此时该数是一个极其大的数字,这样做是为了表⽰±⽆穷⼤(正负取决于符号位s)
重回题目
第一环节
我们先看第1环节,为什么9还原成浮点数,就成了 0.000000呢?我们来逐一分析:
9以整型的形式存储在内存中,得到如下⼆进制序列:
0000 0000 0000 0000 0000 0000 0000 1001
⾸先,将9的⼆进制序列按照浮点数的形式拆分,得到第⼀位符号位s=0,后⾯8位的指数 E=00000000,最后23位的有效数字M=00000000000000000001001,因为E=0,此时原数为一个极其小的数字,所以解引用出来的数为0.000000
第二环节
再看第2环节,浮点数9.0,为什么整数打印是 1091567616呢?
⾸先,浮点数9.0等于⼆进制的1001.0,即换算成科学计数法是1.001*2^3
那么,第⼀位的符号位S=0,有效数字M等于001后⾯再加20个0,凑满23位,指数E等于3+127=130, 即10000010
所以,写成⼆进制形式为0 10000010 001 0000 0000 0000 0000 0000
这个32位的⼆进制数,被当做整数来解析的时候,就是整数在内存中的补码,原码正是 1091567616
本节的内容到此结束了。谢谢您的观看,如果有什么问题或者建议的话,欢迎留言
标签:存储,0000,进制,有效数字,double,浮点数,内存 From: https://blog.csdn.net/2301_78694309/article/details/136974858