加强人社局网站建设,金华seo全网营销,建设银行甘肃省行网站,yahoo搜索引擎提交入口上篇讲解了整形在内存中的存储方式#xff0c;这篇文章就来继续讲解浮点数在内存中的存储方式。
上篇地址#xff1a;
(5条消息) 深度剖析数据在内存中的存储#xff08;上#xff09;_陈大大陈的博客-CSDN博客
目录#xff1a;
3.浮点型在内存中的存储
3.1.浮点数的…上篇讲解了整形在内存中的存储方式这篇文章就来继续讲解浮点数在内存中的存储方式。
上篇地址
(5条消息) 深度剖析数据在内存中的存储上_陈大大陈的博客-CSDN博客
目录
3.浮点型在内存中的存储
3.1.浮点数的范围以及精度 3.2.一个例子
3.3.浮点数存储规则
3.4.解释前面的题目 话不多说咱们开始 3.浮点型在内存中的存储 常见的浮点数 3.1415926 2a13 浮点数家族包括 float、double、long double 类型。 浮点数表示的范围float.h中定义 3.1.浮点数的范围以及精度 我们可以使用一个叫做everything的软件来查找我们需要的文件当然没有也没事只是不太方便
软件链接voidtools 打开everything输入float.h。
然后将float.h拖入vs编译器。 我们可以在里面清楚地看到浮点数类型的最大值最小值和精度。
其中 DBL_EPSILON 表示double类型的精度。 DBL_MIN 表示double类型的最小值。 DBL_MAX表示double类型的最大值。 比葫芦画瓢。 FLT_EPSILONFLT_MAXFLT_MIN则是float类型的数据。 而整形类型的存储范围则可以去limits.h里面来找。 将其拖入编译器可以看到整形数据的各项定义。 其中 SCHAR表示signed charUCHAR表示unsigned char。 SHRT表示 shortUSHRT表示unsigned short。 LLONG 表示long longULLONG表示unsigned long long。 3.2.一个例子 接下来就是重头戏了。大家先来看一道小题。
#define _CRT_SECURE_NO_WARNING
#includestdio.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;
} 输出的结果是什么呢 打印出的数字和我们预想的不太一样我们以为 printf(*pFloat的值为%f\n,*pFloat);所打印出来的值应该是9.000000可结果确实0。当 *pFloat为浮点数时我们
这说明浮点型和整形在内存中的读取方式是不一样的。 3.3.浮点数存储规则 num 和 *pFloat 在内存中明明是同一个数为什么浮点数和整数的解读结果会差别这么大
要理解这个结果一定要搞懂浮点数在计算机内部的表示方法。
详细解读
根据国际标准IEEE电气和电子工程协会 754任意一个二进制浮点数V可以表示成下面的形式: (-1)^S * M * 2^E (-1)^S表示符号位当S0V为正数当S1V为负数。 M表示有效数字大于等于1小于2。 2^E表示指数位 举例来说 十进制的5.0写成二进制是 101.0 相当于 1.01×2^2 。
那么按照上面V的格式可以得出S0M1.01E2。
十进制的-5.0写成二进制是 -101.0 相当于 -1.01×2^2 。
那么S1M1.01E2。 IEEE 754规定 对于32位的浮点数最高的1位是符号位s接着的8位是指数E剩下的23位为有效数字M。
(IEEE 754全称IEEE二进制浮点数算术标准详细解释在下面链接我就不赘述了)
IEEE 754_百度百科 (baidu.com)
32位的浮点数第一位最高位是符号位S紧接的8位是指数位E最后的23位是尾数位M。
而64位的浮点数第一位是符号位S,下面的11位是指数位E最后的52位是尾数位M。 IEEE 754对有效数字M和指数E还有一些特别规定。
前面说过 1≤M2 也就是说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位浮点数时必须保存成10127137即 10001001。
然后指数E从内存中取出还可以再分成三种情况
E不全为0或不全为1
这时浮点数就采用下面的规则表示即指数E的计算值减去127或1023得到真实值再将 有效数字M前加上第一位的1。
比如 0.51/2的二进制形式为0.1由于规定正数部分必须为1即将小数点右移1位则为 1.0*2^(-1)其阶码为-1127126表示为 01111110而尾数1.0去掉整数部分为0补齐0到23位00000000000000000000000则其二进制表示形式为: 0 1111110 00000000000000000000000 E全为0 这时浮点数的指数E等于1-127或者1-1023即为真实值。 有效数字M不再加上第一位的1而是还原为0.xxxxxx的小数。这样做是为了表示±0以及接近于0的很小的数字。 E全为1 这时如果有效数字M全为0表示±无穷大正负取决于符号位s 3.4.解释前面的题目 #define _CRT_SECURE_NO_WARNING
#includestdio.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;
}
为什么 0x00000009 还原成浮点数就成了 0.000000
将0x00000009拆分。
得到下面的结果。 0000 0000 0000 0000 0000 0000 0000 0000 1001 第一位符号位s0后面8位的指数 E00000000 最后23位的有效数字M000 0000 0000 0000 0000 1001。
带入上面所讲的浮点数存储公式为 (-1)^0*0.00000000000000000000000*2^(-126) 这样的数字小到我们无法用数字来写出来所以用十进制小数表示就是0.000000。
再看例题的第二部分。
请问浮点数9.0如何用二进制表示还原成十进制又是多少
我们知道9.0用二进制来表示即为1001.0也即1.001*2^3
可以看出来符号位S为0指数位E为3127130也即10000010尾数位M为1.001。
二进制形式如下。 0 10000010 001 0000 0000 0000 0000 0000 这个32位的二进制数用10进制来计算结果就是1091567616。 数据在内存中存储终于完结了谢谢大家的观看。如果文章有错误请各位不吝赐教。
可以的话不妨给小陈点个小小的赞鼓励一下。
咱们下期再见