码出高效 - 浮点数

博客引用处(以下内容在原有博客基础上进行补充或更改,谢谢这些大牛的博客指导):
浮点数的二进制表示(IEEE 754标准)
二进制如何转十进制,十进制如何转二进制

现代计算机中,一般都以IEEE 754标准存储浮点数,这个标准的在内存中存储的形式为:
在这里插入图片描述

对于不同长度的浮点数,阶码与小数位分配的数量不一样,如下:
在这里插入图片描述
说明:短实数-float 长实数-double

由浮点数–推算出其在计算机中的二进制表示—》二进制:
这里以单精度float为例子
二进制数据的结构:
缺图片这里
解释说明:符号分一位,指数的移码(阶码位)八位,尾数23位(用23位表示24位,前面隐藏一位1,对于规格化表示来说)

178.125

第一步:
先把浮点数分别把整数部分和小数部分转换成2进制 (即使是负数,这里也先不考虑符号问题)
整数部分用除2取余的方法,求得:10110010   (不用补位数,得到几位就是几位)
小数部分用乘2取整的方法,求得:001
合起来即是:10110010.001
转换成二进制的浮点数,即把小数点移动到整数位只有1,即为:1.0110010001 * 2^111,111是二进制,由于左移了7位,所以是111
或者写成1.0110010001 * 2^7 

第二步:
把浮点数转换二进制后,这里基本已经可以得出对应3部分的值了
数符:由于浮点数是整数,故为0.(负数为1)

阶码 : 阶码是需要作移码运算,在转换出来的二进制数里,阶数是111(十进制为7),对于单精度的浮点数,偏移值为01111111(127)[偏移量的计算是:2^(e-1)-1, e为阶码的位数,即为8,因此偏移值是127],即:111+01111111 = 10000110 或者直接算 127+7=134 的二进制

尾数:小数点后面的数,即0110010001   这里1被默认隐藏

最终根据位置填到对位的位置上:
在这里插入图片描述

小数点前面的1去哪里了?
由于尾数部分是规格化表示的,最高位总是“1”,所以这是直接隐藏掉,同时也节省了1个位出来存储小数,提高精度

由二进制数–推算出其浮点数—》浮点数:
符号位
在最高二进制位上分配一位表示浮点数的符号,0表示正数,1表示负数

阶码位
在符号位的右边分配8位用来存储指数,IEEE754标准规定阶码存储的是指数对应的移码,而不是指数的原码或者补码

移码的几何意义:把真值(实际值,十进制数)映射到一个正数域,其特点是可以直观的反应两个真值的大小,即移码大的真值也大,基于这个特点,对计算机来说用移码比较两个真值的大小非常简单,只要高位对齐后逐个比较即可,不需要考虑符号的问题。

由于阶码实际存储的是指数的移码,所以指数与阶码之间的换算关系就是指数与它的移码之间的换算关系,假设指数的真值为e,阶码为E,则有E = e+(2^n-1 -1),其中 2 ^ n-1 -1 是IEEE754标准中规定的偏移量,n=8是阶码的二进制位数(固定就是8)

尾数
最右边连续分配的23位有效数字,IEEE754规定以原码表示,科学计数法进行规格化的目的是保证浮点数的唯一性,如同十进制规格化的要求1 <= |a| < 10 ,二进制数值规格化后的尾数形式为1.xyz ,满足1 <= |a| < 2 ,而为了节约存储空间,讲复合规格化尾数的首个1省略了,这样表面上是23位,却表示了24位二进制数。

计算:
-16 二进制表示 1100-0001-1000-0000-0000-0000-0000-0000
先算阶码8位,算出来二进制数转10进制的值A,比如100-0001-1 对应131(十进制)
然后算出指数(底为2) Z = A-127 (包括正负)
再然后计算尾数值W,如000-0000-0000-0000-0000-0000 得到1.00000000000000000000000
最后计算数值 R = W * 2 ^ Z (-16)

Ps

  • 1-0.9的浮点数计算并不等于0.1 所以以后类似浮点数值相等比较的,还是用大于小于的方式来比较是否相等。

猜你喜欢

转载自blog.csdn.net/fragrant_no1/article/details/84666547