C编程从入门到实践
上QQ阅读APP看书,第一时间看更新

4.5.2 实型变量

实型变量占用的内存比整型变量要多,因为它有小数部分。在一般情况下,一个实型数据占用4字节内存,并且是以指数形式存储的。系统会把一个实型数据分为小数部分和指数部分,分别进行存储,并且需要遵循如下两条规则。

❑ 小数部分占的位(bit)数越多,数值的有效数字就越多,精度就越高。

❑ 指数部分占的位数越多,则表示的数值范围越大。

1.实型变量的分类

在C语言中,实型变量分为单精度(float)型、双精度(double)型和长双精度(long double)型3类。

在Turbo C中单精度型占4字节(32位)的内存空间,其数值范围为3.4E-38~3.4E+38,它只能提供7位有效数字。双精度型占8字节(64位)的内存空间,其数值范围为1.7E-308~1.7E+308,它可提供16位有效数字。具体说明如表4-2所示。

表4-2 实型变量的类别

2.声明实型变量

在C语言中,实型变量的格式和书写规则与整型变量相同,只是将类型设置为“float”和“double”。例如下面的格式。

    float x, y;                                       //x、y为单精度实型变量
    double a, b, c;                                   //a、b和c为双精度实型变量

3.实型数据的舍入误差

由于实型变量是由有限的存储单元组成的,所以它能提供的有效数字是有限的,这样就会存在舍入误差。为了避免产生误差,开发人员要避免将一个很大的数和一个很小的数进行运算,以避免产生舍入误差。

实例4-3

一个很大的数和一个很小的数进行加法运算

源码路径daima\4\4-3

本实例的实现文件为“error.c”,具体代码如下所示。

    #include <stdio.h>
    int main(void)
    {
        float num1, num2;  //定义两个实型变量
        num1=111111111e2; //对一个变量赋很大的值
        num2= num1+10;    //加一个小数
        printf("%f, %f\n", num1, num2);    //输出结果
    }

拓展范例及视频二维码

范例4-3-01:求浮点数的绝对值

源码路径:演练范例\4-3-01\

范例4-3-02:对浮点数进行舍入

源码路径:演练范例\4-3-02\

运行上述程序后输出运算结果,如图4-4所示。

图4-4 执行效果

从图4-4所示的计算结果可以看出,当将很大的实型数据和很小的实型数据进行相加时,其结果不会发生变化。结果中的前8位是准确的,而后几位是不准确的。由此可以得出一个结论,很小的数与很大的数相加后,后面几位是没有任何意义的。

注意:上述代码是对两个差别较大的实型变量进行加法运算。从运算结果可以看出,变量的运算会涉及误差。在现实应用中,还有可能会造成实型数据的溢出。

看下面的代码。

    #include <stdio.h>
    int main(void)
    {
        float a, b, c, d; a=1.2E33; b=0.5E-22; c=0.25E-21; d=a/b; d=d*c;
        printf("c=%f\n ", d);
    }

将上述具体的溢出代码保存到“daima\4\4-3\yichu.c”中,执行上述代码后将会产生溢出错误,这是由于在程序中a/b的运算结果超出了单精度型能表示的范围,所以会产生溢出。为此建议读者在使用时,应避免直接用一个较大的数除以一个较小的数。可以将程序的计算部分d=a/b;d=d*c;改为:d=a*c;d=d/b;或d=a/b*c;以避免发生溢出。也许有人会提出d=a/b*c为什么不产生溢出呢?其原因是,在Turbo C中单精度型数据在计算时要先转换为双精度型数据,计算后再转换为单精度型数据赋给单精度型变量d。