跨境派

跨境派

跨境派,专注跨境行业新闻资讯、跨境电商知识分享!

当前位置:首页 > 平台政策 > 【C语言】数据的存储_数据类型:浮点型存储

【C语言】数据的存储_数据类型:浮点型存储

时间:2024-04-27 16:15:18 来源:网络cs 作者:付梓 栏目:平台政策 阅读:

标签: 数据  类型  语言 
阅读本书更多章节>>>>

常见的浮点数:

3.1415926

1E10 

浮点型包括:float、double、long double类型

浮点数表示的范围:float.h中定义

 浮点数存储规则:

第二个n和*pFloat在内存中明明是同一个数,但浮点数和整数解读结果差别很大。

要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。

详细解读:

根据国际标准IEEE(电子和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:

(-1)^S*M*2^E

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

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

2^E表示指数位

举个栗子:

比如V=5.0,我们先把它转化成二进制即101.0,然后再写成科学计数法的形式即1.01*2^2(第一个2表示是二进制,第二个2表示移两位)所以可以写成(-1)^0*1.01*2^2。

再如V=9.5,我们把它转化为二进制位1001.1(因为最后一个1的权重表示2^-1,即0.5),转化为科学计数法的形式:1.0011*2^3,即(-1)^0*1.0011*2^3。(S=0,M=1.0011,E=3)

又如V=9.6,我们会发现这个数无法转化成二进制,假如说是1001.11,我们会发现小数点后表示0.75,我们发现总是会差一点,从而精度丢失,所以也就是说小数再内存中可能是无法精确保存的,但double类型的精度显然要比float高。

IEEE 754规定:

对于32位的浮点数,最高位的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M。

而对于64位的浮点数,最高位的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。

IEEE 754对有效数字M和指数E有一些特殊的规定:

有效数字M的值是大于等于1,小于2的,所以M可以写成1.xxxxxxxx的形式,其中xxxxxxxx表示小数部分。

IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面xxxxxxxxx的部分。比如保存1.01时,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23,将第一位的1舍去以后,等于可以保存24位有效数字。

相对指数E就比较复杂,首先E是一个无符号整数(unsigned int)这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047,但是我们知道,科学计数法中的E是可以出现负数的,所以IEE 754规定,存入内存E的真实值必须在加上一个中间数,对于8位的E,这个中间数是127;对于11位的E这个中间数是1023.比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001.

#include<stdio.h>int main(){float f = 5.5;//(-1)^0*1.011*2^2//S=0  M=1.011  E=2//0  2+127=129(真实的E加上中间值)即10000001  01100000000000000000000(M)//因此存放的二进制序列为01000000101100000000000000000000//写成十六进制即0x40 b0 00 00(小端存放)return 0;}

 

然而,指数E在内存中取出还可以分成三种情况:

E不全为0,或不全为1

这时浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1.

比如:

0.5的二进制形式为0.1,由于规定整数部分必须为1,即小数点向右移一位,则为1.0*2^(-1),其阶码为-1+127=126,表示为

0 01111110 00000000000000000000000

 E全为0

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,

有效数字M不再加上第一位的1,而还原为0.xxxxxxx的小数。这样做是为了表示+0,以及接近0的很小的数字

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

先看第一部分9的二进制序列为:

00000000000000000000000000001001,我们站在整型的角度去看它,打印出来就是9

而当我们站在浮点型角度

0 00000000 00000000000000000001001

第一个0是符号位表示正数,而E全为0,真实值为-126,表示的数字为(-1)^0*0.00000000000000000001001*2^(-126),是一个无穷小数字

再来看第二部分9.0转化为二进制为:

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

E=3,则存入内存E的真实值为130所以二进制序列为:

0 10000010 00100000000000000000000

站在整型角度0表示正数,所原码、补码、反码相同,这个32的二进制序列转化为十进制,正是1091567616.

 

阅读本书更多章节>>>>

本文链接:https://www.kjpai.cn/zhengce/2024-04-27/162953.html,文章来源:网络cs,作者:付梓,版权归作者所有,如需转载请注明来源和作者,否则将追究法律责任!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

文章评论