dns 本地 网站建设,东莞网站推广多少钱,wordpress 模板 怎么用,怎么在拼多多开网店前言
在上一期中我们讲到了有关于整型在内存中的存储#xff0c;新朋友可以点开#x1f517;了解一下#xff0c;那这一期中我们将讲到的浮点数是不是存储方式和整型一致呢#xff1f;
一、浮点数在内存中的存储
为了探究这个问题我们先来看一段代码
#includestdio…前言
在上一期中我们讲到了有关于整型在内存中的存储新朋友可以点开了解一下那这一期中我们将讲到的浮点数是不是存储方式和整型一致呢
一、浮点数在内存中的存储
为了探究这个问题我们先来看一段代码
#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(n的值为%d\n, n);printf(* pFloat的值为%f\n, *pFloat);return 0;
}
你们觉得运行结果会是什么样的呢让我们来看一看。 二、浮点数存储规则
我们看到上面代码的输出结果是不是有点意料之外其实这都和浮点型在内存中的存储规则有关系。
浮点数在计算机中的存储遵循IEEE 754标准它定义了浮点数的表示和运算规则。根据您提供的图片内容一个浮点数 VV 可以表示为 在IEEE 754标准中浮点数的存储通常分为单精度32位和双精度64位两种格式。单精度浮点数的存储结构如下
1位符号位 SS8位指数位 EE23位有效数字位 MM 双精度浮点数的存储结构如下
1位符号位 SS11位指数位 EE52位有效数字位 MM 指数位 EE 使用偏移量表示单精度浮点数的偏移量是127双精度浮点数的偏移量是1023。这意味着实际存储的指数值需要加上这个偏移量才能得到实际的指数值。
有效数字位 MM 通常使用隐式偏移表示即在有效数字的最高位之前隐含了一个1对于非规格化数或0对于规格化数。这意味着在存储时最高位的1是不存储的从而可以存储更多的有效数字。
举个例子
假设我们有一个十进制数 3.5我们想要将其转换为32位单精度浮点数格式。 确定符号位由于3.5是一个正数符号位 SS 为0。 将数值转换为二进制形式3.5的二进制形式是11.1无限循环小数但在有效数字位内我们只取前几位例如11.1000...。 规范化数值将数值规范化使其形式变为1.xxxxxx * 2^n。对于3.5我们可以将其表示为1.1 * 2^1。 计算指数位 EE规范化后的数值的指数是1加上偏移量127因为这是单精度浮点数得到 E1127128E1127128。128的二进制形式是10000000。 计算有效数字位 MM去掉规范化数值的整数部分1剩下的小数部分是1.1000...。我们只取前23位因为单精度浮点数有23位有效数字位得到0.1100000...。将这个小数转换为二进制我们得到1100000...这里省略了23位之后的位。 组合符号位、指数位和有效数字位将这三部分组合起来我们得到32位的二进制数 符号位 SS0指数位 EE10000000有效数字位 MM1100000...
最终3.5的32位单精度浮点数表示为 0 10000000 1100000000000000000000
三、浮点数的存储过程
对于有效数字M和指数E有一些特别的规定
当1M2M可以写成1.xxxxxx的形式xxxxx表示小数部分。计算机内存保存M时默认这个数的第一位总是1因此可以被舍去只保存后面的xxxxxx部分。
E为一个无符号整型意味着它的取值范围为0~255但是科学计数法中的E是可能出现负数的所以存入内存时E的真实值必须再加上一个中间值 对于8位的E中间值是12711位的E中间值是1023.
3.1浮点数取出过程
3.1.1E不全为0或不全为1 读取符号位 SS这是最左边的一位决定数值的正负。 读取指数位 EE接下来的几位是指数位它们表示数值的量级。 读取有效数字位 MM剩余的位是有效数字位表示数值的精度。 计算实际指数将存储的指数值减去偏移量得到实际的指数。对于32位单精度浮点数偏移量是127对于64位双精度浮点数偏移量是1023。 计算有效数字将有效数字位 MM 转换为二进制小数并在前面加上一个隐含的1对于规格化的数得到 1.M1.M 的形式。 计算数值将 1.M1.M 乘以 22 的 E−偏移量E−偏移量 次幂得到最终的十进制数值。
举个例子假设我们有一个32位单精度浮点数表示为
1 01111011 00100000000000000000000 符号位最左边的位是1表示这是一个负数。 指数位接下来的8位是01111011转换为十进制是123。 有效数字位剩余的23位是00100000000000000000000转换为二进制小数是0.100000...这里省略了23位之后的位。 计算实际指数123 - 127 -4。 计算有效数字1.100000...前面隐含的1加上读取到的二进制小数。 计算数值1.100000...×2−41.100000...×2−4。
将 1.100000...1.100000... 转换为十进制小数我们得到1.0然后乘以 2−42−4即除以16得到最终的十进制数值0.0625。因此这个32位单精度浮点数表示的是-0.0625。
3.1.2E全为0
浮点数指数E等于1-1271-1023)即真实值有效数字M不再加上第一位的1而是还是为0.xxxxx的小时。这样是为了表示-0以及接近0很小的数字。 3.1.3E全为1
这时有效数字M全为0则表示无穷打正负取决于符号位s)
四、题目解析
为了观看方便我们再把开头的代码和运行结果贴在这里。
#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(n的值为%d\n, n);printf(* pFloat的值为%f\n, *pFloat);return 0;
} 为什么这里9还原成浮点数就成了0.000000了呢下面是9以整型存储再内存中得到的二进制序列。 0000 0000 0000 0000 0000 0000 0000 1001 我们将9的二进制按浮点数的形式拆分
得到符号位S0后面8为指数E00000000最后23为有效数字M000 0000 0000 0000 0000 1001.
按照E全为0的规则浮点数V应该等于
V是一个很小的接近0的正数用十进制表示就是0.000000/
再看看浮点数9.0用整数打印为什么是1091567616
浮点数 9.0二进制的1001.0换成科学计数法是1.001*2^3符号位S0有效数字M001后面加20个0指数E312713010000010
所以写成二进制形式应该是SEM 0 10000010 001 0000 0000 0000 0000 0000 整数在内存是补码转换成原码就是1091567616。
本期内容到此结束啦如果对您有帮助的话点亮小星星吧。