计算机也需要运算和存储数学中的实数。在计算机的发展过程中,曾产生过多种存储实数的方式,有的现在已经很少使用了。不管如何存储,我们都可以划分为定点实数存储方式和浮点实数存储方式这两种。所谓定点实数,就是约定整数位和小数位的长度,比如用4字节存储实数,我们可以约定两个高字节存放整数部分,两个低字节存储小数部分。这样的好处是计算的效率高,缺点也显而易见,存储不灵活,比如我们想存储65536.5,由于整数的表达范围超过了2字节,用定点实数存储方式就无法实现了。对应地,也有浮点实数存储方式,道理很简单,就是用一部分二进制位存放小数点的位置信息,我们可以称之为“指数域”,其他的数据位用来存储没有小数点时的数据和符号,我们可以称之为“数据域”、“符号域”。在访问时取得指数域,与数据域运算后得到真值,如67.625,利用浮点实数存储方式,数据域可以记录为67625,小数点的位置可以记为10的-3次方,对该数进行访问时计算一下即可。浮点实数存储方式的优缺点和定点实数存储方式的优缺点是相反的。在80286之前,程序员常常为实数的计算伤脑筋,而后来推出了浮点协处理器,可协助主处理器分担浮点运算,程序员计算实数的效率也就提升了,于是浮点实数存储方式也就普及开来,成为现在主流的实数存储方式。但是,在一些条件恶劣的嵌入式开发场合,仍可看到定点实数的存储和使用。
在C/C++中,使用浮点方式存储实数,用两种数据类型来保存浮点数:float(单精度)、double(双精度)。float在内存中占4字节空间,double在内存中占用8字节空间。由于占用空间大,double可描述的精度更高。这两种数据类型在内存中同样以十六进制方式进行存储,但与整型类型有所不同。
整型类型是将十进制转换成二进制保存在内存中,以十六进制方式显示。浮点类型并不是将一个浮点小数直接转换成二进制数保存,而是将浮点小数转换成的二进制码重新编码,再进行存储。C/C++的浮点数是有符号的。
在C/C++中,将浮点数强制转换为整数时,不会采用数学上四舍五入的方式,而是舍弃掉小数部分(第4章会提到的“向0取整”),不会进位。
浮点数的操作不会用到通用寄存器,而会使用浮点协处理器的浮点寄存器,专门对浮点数进行运算处理,见2.2.2小节。MicrosoftVisualC++6.0在使用浮点数前,需先对浮点寄存器进行初始化,然后才能正常运行。未初始化浮点寄存器的代码如代码清单2-1所示。
代码清单2-1 未初始化浮点寄存器
int main(int argc, char* argv[])
{
// 在未使用到浮点数情况下,
// 在Visual C++ 6.0 中输入小数会报错,因没有对浮点寄存器进行初始化
int nInt = 0;
scanf("%f", &nInt);
}
在代码清单2-1所示的运行程序中输入小数将会导致程序崩溃,这是由于在浮点寄存器没有初始化时使用浮点操作,将无法转换小数部分。
解决办法是:在代码中的任意位置定义一个浮点类型的变量即可对浮点寄存器进行初始化
联系客服