做设计图任务的网站,儿童 html网站模板,新网站百度搜不到,wordpress 自定义字段诸君又该学习了#xff0c;今天我们继续来一睹浮点数的奥妙真容。
经过前面文章对整形提升相关的解释#xff0c;我们都对整形和字符在内存空间上的储存已经有了大概的认知#xff0c;那么现在我们就来好好讲讲浮点数在内存中的储存规则。
目录
浮点数与整形储存的不同
…诸君又该学习了今天我们继续来一睹浮点数的奥妙真容。
经过前面文章对整形提升相关的解释我们都对整形和字符在内存空间上的储存已经有了大概的认知那么现在我们就来好好讲讲浮点数在内存中的储存规则。
目录
浮点数与整形储存的不同
浮点数在内存中的储存规则
浮点数的存储过程
浮点数取的过程 浮点数与整形储存的不同 #includestdio.hint main()
{int a 9;float* p (float*)a;printf(%d\n, a);printf(%f\n, *p);*p 9.0;printf(%d\n, a);printf(%f\n, *p);return 0;
} 那么我们现在可以思考一下这个结果证明了什么呢
是不是就是证明了我们浮点数和整形数据在内存中的储存方式是不一样的而且float类型和int整形所占字节都是4个字节这样更能体现int和float内存储存数据的不一样。那么下面我将展开说一下float在内存中到底如何储存数据的。 浮点数在内存中的储存规则 首先这里我们先看一个公式这使我们等下更好的理解这块知识
V (−1) ^S *M * 2^E,那这里我们可以来来看看这里的SME到底是什么
-1^S 用来取决这个浮点型数据的正负如果为0则为正数如果为1则为负数。 M和E 即为一个大于1小于2的数即1M2,那么后面的2^E也很容易知道了其为一个像科学计数法似的指数。如5.5转化二进制浮点型表示------101.11.011*2^2 那么此时M1.001E2S0 我们这里直接甩图让大家直接看清楚浮点型数据中32位bit是怎么储存打印时又要怎么读取呢。
float型 double型 这样一看诸君是否就清楚许多恍然大悟呢那么先别急这里还需讲一个知识点。
浮点数的存储过程
浮点数存的过程 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。 总结计算机储存的M是直接省略整数为的1的对于指数E我们在其基础上加上127或是1023在存取到计算机内存中至于是加上哪个看是单精度float还是double。 下面我们看一个例子
我们继续拿float a5.5这个数来举例。
这里按照上面的说法。5.5为正数那么S0。
然后将5.5换成二进制101.1在换成科学计数法1.011*2^2此时M1.011然后在计算机中储存时把整数为的1暂时舍去在取出来时在加回去。那么此时计算机中的
M01100000……23bit然后到我们这里的E2。再按照之前的说法在这基础上加上中间数127在储存在计算机中那么此时计算机中的E2127129转换为二进制10000001
然后a在计算机中的储存为0 10000001 01100000000000000000000
然后二进制表示为40 b0 00 00
那么是否就是这样呢我们来用计算机来验证一下 这里VS是小端储存所以我们就看到如图的储存方式 浮点数取的过程
E不全为0或不全为1 这时浮点数就采⽤下⾯的规则表⽰即指数E的计算值减去127或1023得到真实值再将有效 数字M前加上第⼀位的1。 ⽐如0.5 的⼆进制形式为0.1由于规定正数部分必须为1即将⼩数点右移1位则为1.0*2^(-1)其 阶码为-1127(中间值)126表⽰为01111110⽽尾数1.0去掉整数部分为0补⻬0到23位 00000000000000000000000则其⼆进制表⽰形式为:
0 01111110 00000000000000000000000 E全为0 这时浮点数的指数E等于1-127或者1-1023即为真实值有效数字M不再加上第⼀位的1而是还 原为0.xxxxxx的⼩数。这样做是为了表⽰±0以及接近于0的很小的数字。
0 00000000 00100000000000000000000 E全为1 这时如果有效数字M全为0表示±⽆穷大正负取决于符号位s
0 11111111 00010000000000000000000 最后再回到开始的代码
#includestdio.hint main()
{int a 9;float* p (float*)a;printf(%d\n, a);printf(%f\n, *p);*p 9.0;printf(%d\n, a);printf(%f\n, *p);return 0;
} 这里我们一步一步拆分在这段代码中int a9.则是按整形的方式来储存则二进制在计算机中储存为 00000000000000000000000000001001那么在进行这么printf(%f\n, *p);打印时我么会把他当作浮点数的形式进行取出此时S0E为全0按照上面的取出规则
E1-127。计算机中的M00000000000000000001001在加上存之前舍去的1则M100000000000000000001001这么计算起来M*2^-126,非常小接近于0所以打印出来一个
0.000000
然后到第三行打印结果我们将9已浮点数的形式储存浮点数9.0 等于⼆进制的1001.0即换算成科学计数法是1.001×2^3 所以 9.0 (−1) ^ 0 *(1.001) ∗ 2^3 那么第⼀位的符号位S0有效数字M等于001后⾯再加20个0凑满23位指数E等于3127130 即10000010 所以写成⼆进制形式应该是SEM即0 10000010 001 0000 0000 0000 0000 0000
那么按照整形的方式取出来就是一个很大的数即1091567616 文章已到末尾诸君对浮点数储存懂否。