当前位置:网站首页>【C语言进阶】数据的存储【下篇】【万字总结】
【C语言进阶】数据的存储【下篇】【万字总结】
2022-06-10 18:27:00 【你我皆为凡人】
作者:你我皆为凡人
博客主页:你我皆为凡人的博客
名言警句:时间不会为任何人停留,而事物与人,无时不刻也在变化着。每一个人,也都在不停向前!
觉得博主文章写的不错的话,希望大家三连(关注,点赞,评论),多多支持一下!!
系列作品:
文章目录
目录
前言
本文即上篇的文章后讲解了关于浮点型在内存中的存储,一些你不曾了解的知识点,为什么浮点数存储整型打印,整型存储浮点数打印出乎你的意料呢?浮点数是如何存储,又是如何取出呢?看完以后,你的疑惑,将全部得到解决
提示:以下是本篇文章正文内容,下面案例可供参考
浮点型在内存中的存储
常见的浮点数有小数,π,1E10,这种科学计数法
浮点数家族包括 float double long double类型
而浮点数表示的范围在float.h中定义
浮点数存储的例子
先思考一个例子:
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;
}输出的结果为什么会是下面这样呢?

大家先带着这个问题往下看
浮点数存储规则
num 和 *pFloat 在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。详细解读:根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:(-1)^S * M * 2^E(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。M表示有效数字,大于等于1,小于2。2^E表示指数位。
举例来说:
V=5.0f;如何写成二进制呢?
写成二进制为:101.0
写成科学计数法为:1.01*2^2
所以可以具体写成:
(-1)^0 *1.01*2^2 因为是正数,-1的0次方为0,然后我们就得到了:
S=0 M =1.01 E=2
V=9.5f,如何写成二进制呢?
写成二进制为:1001.1(小数点后面的是2的-1次方)
写成科学计数法为:1.0011*2^3
所以可以具体写成:
(-1)^0*1.0011*2^3
S=0 M =1.0011 E=3
但是浮点数存在着一定的精度不准确,比如V=9.6f 写成二进制为1001.后面的值就无法准确判断,可能会超出范围,float--4byte--32个bit位,double--8byte--64bit位,那么可能存在着丢失的问题,存不进去
所以IEEE 754规定:
对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。
对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
IEEE 754对有效数字M和指数E,还有一些特别规定。前面说过, 1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中xxxxxx表示小数部分。IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的 xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位, 将第一位的1舍去以后,等于可以保存24位有效数字。至于指数E,情况就比较复杂。首先,E为一个无符号整数(unsigned int)这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,我们 知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间 数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。然后,指数E从内存中取出还可以再分成三种情况:E不全为0或不全为1这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。比如:0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为1.0*2^(-1),其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进制表示形式为:0 01111110 00000000000000000000000E全为0这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);例如:数据的存储float f = 5.5;101.1 二进制1.011*2^2 科学计数法S=0 M =1.011 E =2 表示S二进制为0 一共1位E真实值2加上中间值127为129 二进制为10000001 一共8位M舍去小数前面的,二进制为011,但是不够,后面补为01100000000000000000000,一共23位转换成十六进制观看为0x40b00000,如图:

如何放进去我们是明白了,那么如何取出来呢?
例如:
数据的取出
常规状态下:
S=0 M =1.011 E =2 表示S二进制为0 一共1位E真实值2加上中间值127为129 二进制为10000001 一共8位M舍去小数前面的,二进制为011,但是不够,后面补为01100000000000000000000,一共23位存储的最后为:0 10000001 01100000000000000000000中间E二进制为129,减去127中间值为2,M加上小数前面的,而S为是0,代表正数(-1)* 0 * 1.01100000000000000000000 * 2^2而全0或者全1的时候,是一个无穷大或者无穷小的数字,一般不会遇到,所以不用过多的研究
例子详解
int main()
{
int n = 9;//整数
//00000000000000000000000000001001
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);//整数的形式放进去,整数的方式拿出来
printf("*pFloat的值为:%f\n", *pFloat);//整数的形式放进去,浮点数的方式拿出来
//00000000000000000000000000001001
//0 00000000 00000000000000000001001
//E =-126
//M =0.00000000000000000001001
//S =0
//+ 0.00000000000000000001001*2^-126
*pFloat = 9.0;//浮点数
//1001.0
// 1.001*2^3
// S=0 E=3 M=1.001
// 0 10000010 00100000000000000000000
printf("num的值为:%d\n", n);//被看成整数打印出来
//0 10000010 00100000000000000000000
printf("*pFloat的值为:%f\n", *pFloat);
return 0;
}
下面,让我们回到一开始的问题:为什么 0x00000009 还原成浮点数,就成了 0.000000 ?首先,将 0x00000009 拆分,得到第一位符号位s=0,后面8位的指数 E=00000000 ,最后23位的有效数字M=000 0000 0000 0000 0000 1001。9 -> 0000 0000 0000 0000 0000 0000 0000 1001由于指数E全为0,所以符合上一节的第二种情况。因此,浮点数V就写成:V=(-1)^0 × 0.00000000000000000001001×2^(-126)=1.001×2^(-146)显然,V是一个很小的接近于0的正数,所以用十进制小数表示就是0.000000。再看例题的第二部分。请问浮点数9.0,如何用二进制表示?还原成十进制又是多少?首先,浮点数9.0等于二进制的1001.0,即1.001×2^3。9.0 -> 1001.0 ->(-1)^01.0012^3 -> s=0, M=1.001,E=3+127=130那么,第一位的符号位s=0,有效数字M等于001后面再加20个0,凑满23位,指数E等于3+127=130,即10000010。所以,写成二进制形式,应该是s+E+M,即0 10000010 001 0000 0000 0000 0000 0000这个32位的二进制数,还原成十进制,正是 1091567616 。
习题练习入口
看完这些不具体操作操作那么是不可以的,可以点击上方直达去练习一些有关习题,也可以随便看一看C语言的一些习题,练习练习选择题和编程题,让自己的知识得到巩固,直接点入标题就可直达,另外想获得大厂内推资格也可以去看看:
总结
一些你不曾了解的知识点,为什么浮点数存储整型打印,整型存储浮点数打印出乎你的意料呢?浮点数是如何存储,又是如何取出呢?看完以后,大家应该了解到,因为两者之间的存储是不一样的,有标准法的表示,有E S M的方法组成,看完以后相信大家的内功又上一层楼,如果觉得博主写的还不错,希望大家多多支持
边栏推荐
- SQL function
- mysql(17-触发器)
- [database language SPL] a simple and fast database language SPL
- AgI foundation, uncertain reasoning, subjective logic Ppt1
- LeetCode_并查集_中等_399. 除法求值
- 直播预告 | 社交新纪元,共探元宇宙社交新体验
- Analysis of optical storage direct flexible power distribution system
- Pits encountered during the use of ETL (ETL Chinese garbled)
- 2022.05.29(LC_6078_重排字符形成目标字符串)
- openSSL1.1.1编译错误 Can‘t locate Win32/Console.pm in @INC
猜你喜欢

Adobe Premiere foundation - material nesting (animation of Tiktok ending avatar) (IX)
![[Agency] 10 minutes to master the essential difference between forward agency and reverse agency](/img/67/5f30f36aa60cf605cbc32399a9d9a0.png)
[Agency] 10 minutes to master the essential difference between forward agency and reverse agency

C knowledge exercise

Design and implementation of SSM based traffic metering cloud system Rar (thesis + project source code)

What are the current mainstream all-optical technology solutions- Part II

Array signal processing simulation part IV -- Z-transform analysis array polynomial

Vs solution to garbled Chinese characters read from txt files (super simple)

北京地铁票务系统

HelloWorld example of TestNG and how to run it from the command line

2022.05.24(LC_674_最长连续递增序列)
随机推荐
MySQL (17 trigger)
AEC:回声产生原因及回声消除原理解析
mysql(17-课后练习题)
基于ssm在线订餐系统设计与实现.rar(项目源码)
Adobe Premiere foundation - time remapping (10)
How to play the Dragon Boat Festival "immersive cloud Tour"? That is to say, it helps "live broadcast +" new scene landing
Beam pattern analysis based on spectral weighting
Adobe Premiere基础-工具使用(选择工具,剃刀工具,等常用工具)(三)
2022.05.26(LC_1143_最长公共子序列)
Openssl1.1.1 compilation error can't locate win32/console pm in @INC
LeetCode_并查集_中等_399. 除法求值
5. golang generics and reflection
Leecode27977 double finger needling
Ranked first in China's SDN (software) market share for six consecutive years
[Agency] 10 minutes to master the essential difference between forward agency and reverse agency
Prospect of database firewall technology [final chapter]
Design and development of hospital reservation registration platform based on JSP Zip (thesis + project source code)
ESP8266 系统环境搭建
Adobe Premiere基礎-工具使用(選擇工具,剃刀工具,等常用工具)(三)
mysql(17-触发器)

