Skip to content

3.3 浮点类型

了解了 C++ 的整形后,我们再来看看浮点类型,它们是 C++ 语言第二梯队的基本类型。所谓浮点类型就是指能够存储带小数部分的数据的数据类型。这听起来像绕口令,我们举个简单的例子。圆的面积公式是: \(S = \pi r^2\),如果 \(r = 2.25\) 这里的 \(2.25\) 就是一个带有小数部分的数,就需要用浮点类型来存储。

“浮点型” 这个名称来源于它在计算机内部存储数据的方式。在这种表示方法中,一个浮点数由两部分组成:尾数(也称为有效数字)和指数。尾数是一个固定精度的数字,指数则用于表示小数点的位置,通过改变指数的值,可以让小数点 “浮动”,所以称为 “浮点型”。例如:对于科学计数法表示的数字 \(2.34 \times 10^4\),其中 \(2.34\) 是尾数,\(4\) 是指数。在计算机中存储的浮点数类似这种形式,但计算机采用二进制编码。

我们之所以要学习使用浮点型,是因为整形无法或者说很难有效地表示一些“超常”的数值范围。例如,我们无法用整形表示太阳到地球的距离(约等于 \(1.496 \times 10^{11}\) 米),或是一些极小的数值。且在诸多领域中很多时候我们都需要用到带有小数部分的数值。

浮点数在计算机中的表示方法与整数有天壤之别,幸运的是我们不必再去过多探究内部实现的细节。我们只需掌握如何使用浮点类型即可。

浮点型精度说明

浮点数的存储方式和有限的位数,可能会导致一些精度问题,比如舍入误差等。在一些连续的计算或者比较运算中,可能会出现意料之外的结果。请务必不要将其用作货币结算或金融相关系统中!应使定点数类型或高精度库。

3.3.1 浮点数表示方法

C++ 有两种浮点数表示方式。

1.第一种是常用的小数点表示法

1.0
1.23
12.34
0.0001
27199.10102

当我们使用浮点类型来保存值时,小数点后即使是 0 小数点也将确保该数字以浮点格式表示即 1.0 而不是 1。

2.第二种是科学计数表示法

1.23E5
-15.3E9
8.33E5
-8.11e-10
9.54E-8
4.02E+7
在科学计数法中,“E”(或 “e”)表示乘以 10 的幂次方

对于 “1.23E5”,其中 “E5” 表示 10 的 5 次方,即 100000,那么就是 \(1.23 \times 10^5\)\(1.23 \times 100000\) 了。

3.3.2 浮点数的类型

有效数字(有效数位)

有效数字是指在一个数中,从该数的第一个非零数字起,直到末尾数字止的数字。这些数字能够真实地反映一个数的精度,用于衡量数据表示的准确性。

在 C++ 中同样也有 floatdoublelong double 三种浮点类型。这些类型数按照它们可以表示的有效数字和允许的指数最小范围来描述的。例如:对于数字 0.0034,它的有效数位是两位(3 和 4),前面的零是用于确定小数点位置的,不是有效数字;而 3.40 这个数字的有效数位是三位(3、4 和最后的 0),最后的 0 表示这个数字精确到了百分位。

对于浮点型数据,有效数位是衡量其精度的重要指标。如单精度浮点数(float)大约有 6-7 位有效数字,双精度浮点数(double)大约有 15-16 位有效数字。例如:一个 float 类型的数值表示为 3.141592(实际上由于 float 精度限制,这可能已经存在舍入误差),其有效数位约为 6 位;而对于一个 double 类型表示为 3.141592653589793,有效数位约为 15 位。

事实上,C 和 C++ 对于有效位数的要求是 float 至少 32 位,double 至少 48 位,且不少于 float,而 long double 至少要和 double 一样多。这三种数据类型的有效位数可以一样多,不过通常,float为 32 位,double为 64 位,long double为 80、96 或 128 位。而它们的指数范围则至少是 -37~37。

存储位与有效数字的区别

  • 存储位:

存储位是指在计算机存储设备(如内存、硬盘等)或数据存储格式中,用于存放数据的最小单元。它主要是从数据存储的物理或逻辑空间角度来考虑的。例如:一个有符号的 8 位整数(存储位为 8 个),可以表示的范围是 -128~127,它通过这些存储位的二进制组合来实现数据的存储。

  • 有效数字:

有效数字是指在一个数中,从该数的第一个非零数字起,直到末尾数字止的数字。它主要用于表示测量或计算结果的精度。

3.3.3 浮点常量

在程序中书写浮点常量的时候,程序将把它存储为哪种浮点类型呢?在默认情况下,像 8.24 和 2.4E8 这样的浮点常量都属于 double 类型。如果希望常量为 foat 类型,请使用 fF 后缀。对于 long double 类型,可使用 lL 后缀(由于 l 看起来像数字 1,因此 L 是更好的选择)。

下面是一些范例: 1.234f // 浮点常量 2.34E20F // 浮点常量 2.345324E28 // 双精度浮点常量 2.2L // 长双精度浮点常量

3.3.4 浮点数的优缺点

浮点数是一种用于表示实数的数值类型,在计算机编程和科学计算中被广泛使用。它有自身独特的优势,但也存在一些缺点。

优点

1.能表示大范围的数值

浮点数可以表示非常大或非常小的数值。例如,在科学计算中,常常会遇到极大或极小的数值,像宇宙中天体的质量(非常大)、微观粒子的尺寸(非常小)等。以常见的双精度浮点数(double)为例,它能表示的数值范围大约是 \(\pm1.7\times10^{-300}\)\(\pm1.7\times10^{308}\) ,这使得它能够处理各种极端情况下的数值计算。

2.适合近似计算

在很多实际应用场景中,并不需要精确表示所有数值,只需要一个近似值即可。浮点数可以在一定精度范围内提供对实数的近似表示,满足大多数实际问题的需求。比如在物理模拟、金融计算中的利率计算、图形图像处理中的颜色值表示等领域,使用浮点数进行近似计算可以在保证一定精度的前提下,提高计算效率。

3.支持小数运算

浮点数能够直接表示和处理小数,这在许多实际应用中是必不可少的。例如,在商业计算中涉及到货币金额的计算,或者在工程领域中对物理量(如长度、重量、速度等)的测量和计算,都需要处理小数部分。使用浮点数可以方便地进行这些小数运算,而无需额外的转换和处理。

缺点

1.存在精度损失

浮点数在计算机中是以二进制形式存储的,而二进制无法精确表示所有的十进制小数。这就导致在进行浮点数运算时,可能会出现精度损失的问题。例如,对于十进制小数 0.1,它无法用二进制浮点数精确表示,在计算机中存储和计算时会存在一定的误差。这种精度损失在多次运算累积后可能会变得比较明显,影响计算结果的准确性。

2.运算速度相对较慢

相比于整数运算,浮点数运算通常需要更多的硬件资源和时间。这是因为浮点数的表示和运算规则更为复杂,需要专门的浮点运算单元(FPU)来处理。在一些对性能要求极高的应用场景中,浮点数运算的速度可能会成为瓶颈。例如,在实时游戏开发、高性能计算等领域,大量的浮点数运算可能会导致程序运行缓慢。

3.比较操作存在风险

由于浮点数存在精度损失,直接使用相等运算符(如 == )来比较两个浮点数是否相等是不安全的。两个理论上应该相等的浮点数,由于精度误差,在计算机中存储的二进制表示可能会有微小差异,导致比较结果为不相等。在进行浮点数比较时,通常需要设置一个合适的误差范围(例如一个很小的常量),通过判断两个浮点数的差值是否在这个误差范围内来确定它们是否近似相等。

笔记

浮点数在表示大范围数值和进行近似计算方面具有优势,但在精度、运算速度和比较操作等方面存在一些缺点。在实际应用中,需要根据具体的需求和场景来选择合适的数据类型。

Comments