1.浮点数的十进制表现形式
·我们知道,在 十进制中通常一个浮点数可以用科学计数法来表示,举例:
eg.1 -306.5可以表示为-0.3065*10^3
其中 - 是符号,指数3是阶或称阶码,0.3065是小数部分,左右两端非0包起来的部分是有效值,此例中的有效值是3065。由于小数部分也称为尾数,所以3065也是尾数。
eg.2 -3.87
其中,有效值为387,尾数为87
·为什么称为浮点数呢?
因为他可以表示为 -3.065*10^2 也可以表示为 -0.03065*10^4 等,小数部分可以左右“浮动” ,但不管小数部分怎么移动,其有效值保持不变,都是3065(注意:尾数是变化的)。于是,两个浮点数相加就先要通过小数点的左右浮动,将阶码对齐后进行尾数相加。
(当阶码为固定值时,数的这种表示法称为定点表示,这样的数称为“定点数”;当阶码为可变时,数的这种表示法称为浮点表示,这样的数称为“浮点数”。)
·十进制浮点数规格化
为了使有效值和尾数能够统一,在空间上表达更有效率,有必要将所有浮点数规格化。
规格化标准:通过调整阶码将浮点数写成小数点前不含有有效数字,小数点后第一位由非0数字表示,举例-306.5规格化为-0.3065*10^3。
2.十进制浮点数转换为二进制浮点数
在计算机内部,浮点数都是以二进制表示的。所以对于十进制浮点数,我们要把它先转换为二进制浮点数。
分两步走:
a.整数部分的转换,采用"除2取余法"。
b.小数部分采用"乘2取整法"。即把小数部分乘2(第一次计算),所得结果的整数部分作为小数的十分位,所得结果的小数部分再乘2(第二次计算),第二次计算所得结果的整数部分作为小数的百分位...以此类推,直到达到所需精度。
3.二进制浮点数的尾数及规格化
当十进制浮点数转换完成二进制浮点数后,就要像十进制数那样对二进制数规格化,以便于计算机表示。
·二进制浮点数的规格化
规格化标准:通过调整小数点的阶码使得该数的有效值在1和2之间,既二进制浮点数的整数部分为1。
例如:0.8125 = 0.1101(二进制) = 1.101*2^(-1)
注意:上例末尾的(-1)是阶码,它也是二进制表示。然而,提到阶码就不得不提移码(增码),计算机移码就是在原有的补码的基础上对于符号取反。
·那么为什么会用移码来表示阶码呢?
因为用补码表示阶码的时候,当阶码无限小,产生了下溢的时候,阶码变成了0,那么这个浮点数的值变为了1。而实际上这个数是无限接近于零的。那么我们就需要取出其中的 "-0“ 值作为机器零。
4.计算机二进制浮点数表示过程
先看浮点数二进制表达的三个组成部分:
主要成分是:
- Sign(1bit):表示浮点数是正数还是负数。0表示正数,1表示负数
- Exponent(8bits):指数部分。类似于科计数法中的M*10^N中的N,只不过这里是以2为底数而不是10。需要注意的是,这部分中是以2^7-1即127,也即01111111代表2^0,转换时需要根据127作偏移调整。
- Mantissa(23bits):尾数部分。浮点数具体数值的实际表示
实例:
Step 1 改写整数部分
以数值5.2为例。先不考虑指数部分,我们先单纯的将十进制数改写成二进制。
整数部分很简单,5.即101.。
Step 2 改写小数部分
小数部分我们相当于拆成是2^-1一直到2^-N的和。例如:
0.2 = 0.125+0.0625+0.007825+0.00390625即2^-3+2^-4+2^-7+2^-8….,也即.00110011001100110011
Step 3 规格化
现在我们已经有了这么一串二进制101.00110011001100110011。然后我们要将它规格化,也叫Normalize。其实原理很简单就是保证小数点前只有一个bit。于是我们就得到了以下表示:1.0100110011001100110011 * 2^2。到此为止我们已经把改写工作完成,接下来就是要把bit填充到三个组成部分中去了。
Step 4 填充
指数部分(Exponent):之前说过需要以127作为偏移量调整。因此2的2次方,指数部分偏移成2+127即129,表示成10000001填入。
尾数部分(Mantissa):除了简单的填入外,需要特别解释的地方是1.010011中的整数部分1在填充时被舍去了。因为规格化后的数值整部部分总是为1。那大家可能有疑问了,省略整数部分后岂不是1.010011和0.010011就混淆了么?其实并不会,如果你仔细看下后者:会发现他并不是一个规格化的二进制,可以改写成1.0011 * 2^-2。所以省略小数点前的一个bit不会造成任何两个浮点数的混淆。