新乡网站建设设计公司,新手学做网站学哪些知识,网站关键词作用,wordpress加载图片慢目录 前言#xff1a;
引言#xff1a; 浮点数存储规则
举个栗子#xff1a;
TIP#xff1a;
单精度浮点数存储的模型#xff08;float#xff09;
双精度浮点数存储的模型#xff08;double#xff09;
IEEE对 M 的特殊规定
IEEE对 E 的特殊规定
小试牛刀
先… 目录 前言
引言 浮点数存储规则
举个栗子
TIP
单精度浮点数存储的模型float
双精度浮点数存储的模型double
IEEE对 M 的特殊规定
IEEE对 E 的特殊规定
小试牛刀
先看第一段代码
再看第二段代码 前言
我们首先需要知道什么是浮点型以下是两种常见的浮点型。
3.14159 ------------- 这是最常见的浮点型也就是小数。
1E10 ------------- 这个也表示浮点型E表示底数10而E后面的数表示指数所以E10就是10^10,而E前面的1是数量级综上1E10就是1*10^10。
引言
我们先看一段代码
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;
}
输出结果 我们不难发现当n以整型的方式存进去然后分别以整型和浮点型的方式取出发现以浮点型的方式打印结果有问题对应的当n以浮点型的方式存进去再以整型的方式取出结果也是跟我们想象的不一样。
由此可以得出一个结论浮点型在内存中的存储和整型在内存中的存储是不一样的。 浮点数存储规则
根据国际标准IEEE任意一个二进制浮点数V可以表示成下面的形式
-1^ S * M * 2 ^ E(-1) ^ S表示符号位当S0V是正数当S1V是负数。M表示有效数字大于等于1小于22^E表示指数位。
举个栗子
十进制表示的5.5
首先5的二进制位就是101而小数部分0.5我们就用1来表示最终结果就是101.1
为何小数部分用1表示就可以呢
因为整数部分个位数的权重是2^0,十位数的权重是2^1,百位数的权重是2^2,以此类推小数部分的第一位表示2^-1,也就是0.5小数部分的第二位就是2^(-2)……
因此我们用IEEE表示就是
-1^ 0 * 1.011 * 2 ^ 2
所以S0M1.011E2
TIP
理论上任何一个浮点型都可以用IEEE表达形式表示但如果浮点数过于复杂就不能精准的表示出来。
比如3.14小数部分想要表示出0.14需要我们一直凑但大概率是凑不出来会有一些误差
单精度浮点数存储的模型float
对于32位的浮点数最高的1位是符号位S接着的8位是指数E剩下的23位比特位是有效数字M 双精度浮点数存储的模型double
对于64位的浮点数最高的1位是符号位S接着的11位是指数E剩下的52位为有效数字M IEEE对 M 的特殊规定
前面说过1M2,所以M可以写成1.xxxxxxxx的形式其中xxxxxxxxx表示小数部分。
IEEE规定在计算机内部保存M时默认这个数的第一位总是1因此可以被舍去只保存后面的xxxxxxx小数部分。
比如保存1.01时只保存01等到读取的时候再把第一位的1加上去。这样做的目的是节省1位有效数字是的表达小数部分更精确。
IEEE对 E 的特殊规定
首先E作为一个无符号整数unsigned int
这意味着如果E为8位它的取值范围是0~255如果是11位他的取值范围是0~2047。
但是我们知道科学技术法中是可以出现负数的。
所以IEEE规定存入内存时E的真实值必须加上一个中间数对于8位的E来说这个中间数的值就是127对于11位的E来说这个中间值就是1023。
我们取出来时还是需要减去中间数的。 上面讲的内容是讲E如何存储到内存中的下面开始讲解如何把E取出来。
E不为全0或不全为1
这是最普遍的情况我们将指数E的值减去127或1023得到真实值再将有效数字M前加上第一位的1 E全为0
表示原有的真实值是-1272^-127是一个非常小的数字无限接近于0所以有效数字M不再加上第一位的1而是还原0.xxxxxxxx的小数使得接近于0。
E全为1
表示是2^128次方是一个非常大的数字所以表示正负无穷大正负取决于符号位S。
小试牛刀
我们现在已经大致掌握了浮点型在内存如何存储和取出让我们来解决一下引言的问题吧
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在整型n中的存储形式是
00000000000000000000000000001001
然后我们照搬将其存储在浮点型
0 00000000 00000000000000000001001
S E M
可以看出E是全0根据IEEE规定当E为全0时我们对于M不需要补数字1而现在的M也是一个非常小的数字当我们用%f打印时只能保留6位有效数字因此打印结果就是0.000000
再看第二段代码
我们首先是将9.0存储再一个浮点型中
9.0在浮点型中存储的二进制位表达形式是
1001.0
1.001*2^3 (注意一定要表示成科学技术法的形式再找S、M、E)
S0 M1.001存储在内存就是001 E33127
0 10000010 0010000000000000000000
注意M 001存储直接放在最前面
而将这一部分照搬到整型发现结果就是一个非常大的数字1091567616