1 浮点数概述
(资料图)
浮点数是计算机存储实数的一种方式。它无法存储任意的十进制实数,部分实数仅能在浮点数定义的精度下近似表示。在计算机中,普遍使用的是IEEE 754标准的浮点数,包括一个32位的单精度浮点数与64位的双精度浮点数。
浮点数分为三部分,符号位(Sign)、指数位(Exponent)、基数(Mantissa)位。
设符号位为 S ,指数位为E,基数位为 M ,浮点数可以基本表示为:(−1)S×2E×M
以上公式只是对浮点数进行大致的说明。在实际的浮点数中,它所代表的十进制并不是使用直接上述公式计算,对于指数位与基数位在不同标准中有着不同的规定。不要用以上公式进行浮点数的十进制转换
2 IEEE 754的32位浮点数表示
IEEE 755 标准中,规定了符号位为1位、指数位为8位、基数位为23位。
在IEEE754标准中,除了上述的浮点数的说明外,有几处不同:
以上说明可能不够充分,接下来通过讲解一个十进制数如何表示成一个近似的浮点数来说明该标准下浮点数表示方法。
3 十进制数转换为浮点数(IEEE754 32位)
接下来,以实数3.14来做例子,讲述如何将十进制数转换为浮点数。
1. 判断该数是否在表示范围内: 2−126<3.14<2127 ,在该范围内,可以表示。
2. 将整数部分进行二进制转换:3=11
3. 将小数部分进行近似转换:
在实数中,存在十进制小数无法使用表示的数。譬如 1/3、1/7。这是因为十进制小数只能表示能转换为10的次方为分母的分数。(譬如 1/5 可以表示为十进制小数,因为它能转换为2/10,1/25同理,因为它可转换为4/100)
二进制小数则比十进制小数能表示的分数更少,因为其仅能表示能转换为以2的次方为分母的分数。因此,十进制小数不能一一对应一个二进制小数。
综上所述,十进制小数仅能通过一个近似的二进制小数表示。其方法如下:
以上步骤要重复进行多次来取得多位小数。但只能使整个基数部分保留24位。解决该问题可以如下操作:
如果在计算中出现了循环小数或是已经为0的情况,二进制小数计算可以提前停止。
注意到,在整个转换浮点数的第一步已经判断了浮点数的范围,无需考虑十分小的小数无法表示,而近似为0的情况。
通过上述操作,0.14的二进制表示为:0.0010010000111001010110
4. 实数二进制转换:
3.14的二进制表示为:11.0010010000111001010110
5. 实数规格化:
基数需要从二进制数的第一个1开始表示,3.14的规格化表示为:1.10010010000111001010110×21。
6. 指数位计算
3.14规格化后的指数为1,但根据IEEE标准,实际指数位需要在规格化表示的指数上加上127,则指数位为: 127+1=128=10000000
7. 基数位表示
根据IEEE标准,基数位仅表示1.XXXXX后的.XXXXX部分,则3.14的浮点数的基数位为:10010010000111001010110
8. 结果
结合得到的指数位和基数位,再加上符号位0(如果是负数则为1),3.14的完整32位浮点数表示为:0 10000000 10010010000111001010110
4 浮点数转换为十进制数(IEEE754 32位)
根据上述过程,我们不难得出浮点数的十进制表示公式:
设符号位为 S ,指数位为E,基数位为 M ,则32位浮点数代表的十进制数计算公式为:
5 浮点数表示的不准确性
从十进制转换为浮点数的过程中,我们可以看出使用浮点数来表示一个实数时存在的误差在两个地方产生:
十进制小数的二进制转换,许多十进制小数部分只能近似转换成二进制小数。基数位数限制,即使十进制数存在一个精确的二进制数,由于浮点数的位数限制,只能保留固定位数的有效数字。
因此,在编程中使用浮点数实际上并不准确。即使浮点数的加减乘除计算是准确的,浮点数本身不准确,其结果也不会准确。如果要进行精确计算,使用整型才是最佳选择。