引言
今天写了这样的一道题目,刚开始我就直接以为二者之间就只有9.0跟9的区别而已。
结果最后的结果是这样的
为什么会出现这样的结果呢,这可能便是由于浮点数的存储方式与整形并不是适用于同一套规则。
浮点数的储存规则
一个数可以转化成二进制,浮点数也不例外,正如 5.5 转换之后就变成了101.1,小数点左边的各位都表示为 2^0 2^1... 而右边的各位表示为2^-1 2^-2...;也正是因为如此浮点数也会出现由于精度不够而出现的数据丢失现象。
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^S表示符号位,当S=0,为正数;当S=1,为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位。
因为中间的那个数是大于等于 1 小于 2 的所以通过移动小数点来实现正如十进制那样,移了几个就乘上该进制位数的次方,经过转换之后 5.5 就变成了 1.011 * 2 ^ 2 .
对于32比特位的浮点数来说,分配给S一位 8位分给了E剩下的23位分给了M,成如下的形式.
而对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M
同时,在储存的时候由于M必定位于1~2之中第一位数带 1 是必然现象,因此为了节约数位,将M小数点前的1舍去,需要应用的时候再加上.
至于E它是一个无符号类型的整型,意味着它的取值为0~255是没有负数的,为了避免负数的产生,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数 是127;对于11位的E,这个中间 数是1023。在加上这个数之后并转为二进制进行储存.那现在我们的S 为0 E为129转换成二进制位则为 1000 0001 M为 011 剩余的位则用 0 来补齐.
于是我们最终的结果就是 0100 0000 1011 0000 0000 0000储存在内存里面.
从内存中使用的条件
E不全为0或不全为1
则直接加上127并给 M 加上1
E全为0
浮点数的指数E等于1-127(或者1-1023)
E全为1
如果有效数字M全为0,表示±无穷大(正负取决于符号位s);
问题解决
于是我们现在便有能力来解决刚刚那道题目了.
0x00000009就变成了 S 为0, E 也为0, M为000 0000 0000 0000 0000 1001的数,
那我们便可列出表达式 (-1)^0*2*(-127)*9为一个十分接近 0 的正数因为太小所以直接打印0出来;
而9.0在内存中存储形式是 (-1)^0*2^3*1.001;S = 0 E = 3+127 = 130 M = 1.001,转换成二进制位则是 0100 0001 0001 0000 0000 0000 0000 0000
而这个数换算成十进制则为
于程序所得出的答案相同.
如此我们便搞懂了浮点数类型的数据是如何在内存之中存储的,以及该如何使用,找到与整型之间的区别,本体就是考察整型存储的数据换算成浮点型,以及浮点型数据转化为整型.刚开始可能有些生疏但是看久用久了自然就会熟悉.