C++ 文本内容如何转换成单精度浮点数转换型,再从内存中读出,转成文本?

一. 前言在学习了C语言有一段时间以后,对函数,结构体,指针等等都有了初步认识,一些朋友可能在平时在使用数据类型时会出现一些错误,今天笔者带大家清楚地了解一下数据是如何存储,如何取出,本文中主要讲的是整型数据以及浮点型数据的存入取出(环境配置:vc2022,x64)。二.数据类型初认识1. 基本的内置类型这里对数据长度再做一下补充:对各个数据类型取值范围感兴趣的,可以看看limits.h与float.h这两个头文件, limits.h定义了整数的取值范围,float.h定义了浮点数的取值范围2. 数据类型的分类2.1.整型:以常用的int类型为例,unsigned int 就是无符号整型, signed就是有符号整型了,而signed int 就是有符号整型,一般在编译器里都是默认有符号的。可能有朋友对char会有疑问,但实际上char也属于整型,char存入的是字符的acsii码值,本质上存入的还是整型数据。2.2.浮点型:2.3.自定义类型:2.4.指针类型这里的指针类型只是举出一部分例子,根据上面的数据类型,也都有对于的指针类型。2.5.空类型三.前置知识1.原码反码补码1.1.二进制中原码反码补码的计算方法1.2.原码反码补码的转换1.3.为什么要存放补码而不是原码实际上我们的cpu只有加法器,使用补码可以将符号位和数值域统一处理,加法和减法也可以统一处理,在补码和原码之间的转换上,计算的方式也是相同的,也不需要额外的硬件电路。2.大小端存储模式2.1. 大小端介绍知道了数据以二进制形式存进内存中,我们再来看看数据在内存空间中如何存放。可以看到,a,b在内存是以补码的方式存储的,但a,b的值是倒着放的,这就涉及到数据在内存中的存储的方式。大端字节序存储:高位数据存储在低地址,低位数据存储在高位。小端字节序存储:低位数据存储在低地址,高位数据存储在高位。我们可以看到内存窗口1中的两个地址是从低到高的,故a在内存中存储时也是低位数据存储在低位,即小端存储。2.2.为什么有大小端模式在我们的操作系统中,一个地址单元对于一个字节,即8bit,由于我们每种类型数据长度不同,则必然存在将一个数据的不同位分开存储,拿上述的int型举例,一个int型数据4字节,即需要4个地址单元存储,这就有了大小端存储之分,即将数据正着放,或者反着放,当然到底使用哪种模式则是取决于编译器,像常用的x86,以及笔者用的x64就是小段存储模式,而 KEIL C51 则为大端模式,甚至有些ACM处理器还可以由硬件选择大端还是小端模式。四.对于数据类型的一些思考1.数据类型存在的必要性emmm,有些朋友可能会觉得用一种数据类型概括所有数据不就行了,这么多数据类型是不是没有必要。实际上我们的生活中本来就有很多的数据类型,有非常大的数据,有非常小的数据,有小数,有整数,用一种数据类型最后不还是要对数据进行区分,丰富的数据类型实际上是和我们的现实生活完全对照起来的,数据的符号也是这个道理。2.数据类型的意义2.1.确定了数据的使用范围从上面的图片我们可以看到,我们定义一个整型数据a,当把它赋值给一个char型数据b时,可以看到b只能访问1个字符,而a是有4个字符的,这就是数据类型的第一个意义,确定了内存中开辟空间的大小,进而控制了对数据的使用范围。2.2.看待内存空间的视角同样是刚刚的例子,当我把a赋值给b,编译器看向内存空间时就认定了它是一个char型数据,而不再是整型数据,这就是数据类型的第二个作用。五.整型数据的存入取出整型数据在内存中的存储其实是比较简单的,在上文讲解原码反码补码就已经说清楚了,数据以补码的形式存入,打印时以原码显示。六.浮点型数据的存入取出1.浮点型数据的存入由上述例子其实可以看到,整型数据和浮点型数据表示一个数时结果时天差地别,这就说明整型数据和浮点型数据存储时是有区别的,要想理解为什么会造成这样一个结果,就得明白浮点型数据是如何存储的。详细解读:根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:(-1)^S * M * 2^E其中(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。M表示有效数字,大于等于1,小于2。2^E表示指数位。举例来说: 十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2^2 。 那么,按照上面V的格式,可以得出s=0,M=1.01,E=2。十进制的-5.0,写成二进制是 -101.0 ,相当于 -1.01×2^2 。那么,s=1,M=1.01,E=2。IEEE 754规定:对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。对于64位的浮点数,最高的1位是符号位s,接着的11位是指数E,剩下的52位为有效数字M。以上,就基本是我们浮点型数据存入的过程。先以二进制表示,再得出S,M,E的值,最后写成 (-1)^S * M * 2^E的形式。我们观察(-1)^S * M * 2^E这个形式,实际上可以发现M,E这两个数据在存入时是有很大学问的。IEEE 754对有效数字M和指数E,还有一些特别规定。M我们知道,取值范围是1≤M<2的,即M可以写成1.xxxxxxx的形式,xxxxxxx表示小数部分。关于M:IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。关于E:首先,E为一个无符号整数(unsigned int) 这意味着,如果E为8位,它的取值范围为0-255,11位时,E的取值范围是0-2047。但是,我们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。2.浮点型数据的取出浮点型数据取出最大的区别还是在指数E上,指数E从内存中取出还可以再分成三种情况:2.1.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 000000000000000000000002.2.E全为0这时,浮点数的指数E等于1-127(或者1-1023)即为真实值, 有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。因为按照正常取出时E= 0-126=-126,计算出来就是一个非常接近0的数了 ,E全为1同理。2.3.E全为1这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)。3.对浮点数的一些思考大家可以仔细看看浮点数的表示形式————(-1)^S * M * 2^E,由于2的负一次方为0.5,实际上会出现一些浮点数在表示时要一直往后借一位,甚至完全不能精确表示的情况,所以在浮点数的表示中是存在四舍五入的,而浮点数在比较时也不能简单的用“==”,真的要比较的话,可以比较两个浮点数的差值,当然这里就不再具体讲了。了解了浮点型数据的表示后,我们就可以回到一开始的例子中。来到例子的第二部分以上,就是对整型数据和浮点型数据的存储的大致介绍。}

我要回帖

更多关于 单精度浮点数转换 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信