实数型: float
、double

1、概念介绍
实数型(Floating-Point Types),也叫浮点型,用于存储带有小数部分的数字。
float
: 单精度浮点数。通常占用4个字节(32位),精度较低(约7位有效数字),表示范围也较小。double
: 双精度浮点数。通常占用8个字节(64位),是C++中默认的浮点类型。它的精度更高(约15-17位有效数字),表示范围更大。在信息学竞赛中,几乎总是使用double
,因为float
的精度通常不够。
2、使用步骤
- 声明 :
double pi;
- 初始化 :
double pi = 3.1415926535;
- 使用 :
double area = pi * r * r;
3、算法可视化SVG图示
浮点数在内存中的存储比整数复杂,遵循IEEE 754标准,分为三个部分:符号位(Sign)、指数位(Exponent)和尾数位(Mantissa/Fraction)。

double (8 字节 / 64位) 内存结构
- S (Sign) : 1位,表示正负。
- Exponent: 11位,用于存储科学计数法中的指数。
- Mantissa: 52位,用于存储小数的有效数字。
4、核心特性
- 非精确性 : 浮点数是近似表示。大多数小数(如0.1)无法用二进制精确表示,会导致微小的精度误差。
- 范围广: 可以表示非常大或非常接近于0的数。
- 比较陷阱 : 由于精度误差,绝对不能用
==
直接比较两个浮点数 。应该比较它们的差的绝对值是否小于一个极小的数(称为epsilon,如1e-7
)。
5、C++代码基础实现
c
#include <iostream>
#include <iomanip> // 用于控制输出格式,如 setprecision
#include <cmath> // 用于数学函数,如 fabs (取绝对值)
int main() {
// 1. 声明和初始化
float f_pi = 3.1415926f; // 'f'后缀表示 float
double d_pi = 3.141592653589793;
std::cout << std::fixed << std::setprecision(10); // 设置固定小数点格式,并显示10位小数
std::cout << "Float PI: " << f_pi << std::endl;
std::cout << "Double PI: " << d_pi << std::endl;
// 2. 演示精度问题
double a = 0.1;
double b = 0.2;
double c = 0.3;
if (a + b == c) {
std::cout << "0.1 + 0.2 == 0.3" << std::endl;
} else {
std::cout << "0.1 + 0.2 != 0.3" << std::endl; // 这行会被输出
std::cout << "a + b = " << a + b << std::endl;
}
// 3. 正确的比较方式
const double EPSILON = 1e-9; // 定义一个极小数
if (std::fabs((a + b) - c) < EPSILON) {
std::cout << "abs((a+b)-c) is small enough, they are considered equal." << std::endl;
}
return 0;
}
6、优化策略
- 优先使用
double
: 在竞赛中,除非内存限制极其严格,否则始终使用double
来避免不必要的精度问题。 - 避免不必要的浮点运算: 浮点运算比整数运算慢。如果一个问题可以用整数解决(例如,通过扩大倍数将小数转为整数),应优先使用整数。
7、优缺点
- 优点:
-
- 能表示小数和极大/极小的数。
- 缺点:
-
- 存在精度误差,不完全精确。
- 运算速度慢于整数。
- 比较复杂,容易出错。
8、应用场景
- 几何问题: 计算距离、面积、角度等。
- 科学计算: 物理模拟、数据分析。
- 需要除法的场景: 计算平均值、比例等,结果可能为小数。
9、扩展
long double
: 精度更高的浮点类型(通常10或16字节),在极少数需要超高精度的题目中使用。- 科学计数法 : C++中可以用
e
或E
表示科学计数法,例如double light_speed = 2.99792458e8;
// 表示 2.99... × 10⁸
10、5个课后配套练习及C++代码实现答案
练习1: 计算圆的面积
-
题目 : 输入一个双精度浮点数
r
代表圆的半径,计算并输出圆的面积。π 取 3.1415926535。 -
答案:
c#include <iostream> #include <iomanip> int main() { double r; const double PI = 3.1415926535; std::cin >> r; double area = PI * r * r; std::cout << std::fixed << std::setprecision(7) << area << std::endl; return 0; }
练习2: 华氏度转摄氏度
-
题目 : 输入一个华氏温度
F
,根据公式C = 5/9 * (F-32)
计算并输出摄氏温度C
。 -
答案:
c#include <iostream> #include <iomanip> int main() { double fahrenheit; std::cin >> fahrenheit; // 注意:5.0/9.0 确保是浮点数除法 double celsius = 5.0 / 9.0 * (fahrenheit - 32); std::cout << std::fixed << std::setprecision(4) << celsius << std::endl; return 0; }
练习3: 计算平均分
-
题目: 输入三个浮点数,代表三门课的成绩,计算并输出平均分。
-
答案:
c#include <iostream> #include <iomanip> int main() { double score1, score2, score3; std::cin >> score1 >> score2 >> score3; double average = (score1 + score2 + score3) / 3.0; std::cout << std::fixed << std::setprecision(2) << average << std::endl; return 0; }
练习4: 两点间距离
-
题目 : 输入四个浮点数
x1, y1, x2, y2
,代表平面上两个点的坐标,计算并输出这两点间的欧几里得距离。 -
答案:
c#include <iostream> #include <iomanip> #include <cmath> // for sqrt int main() { double x1, y1, x2, y2; std::cin >> x1 >> y1 >> x2 >> y2; double dx = x1 - x2; double dy = y1 - y2; double distance = std::sqrt(dx * dx + dy * dy); std::cout << std::fixed << std::setprecision(5) << distance << std::endl; return 0; }
练习5: 判断三角形
-
题目: 输入三个浮点数 a, b, c,判断它们是否能构成一个三角形。
-
答案: (提示:两边之和大于第三边,注意浮点数比较)
c#include <iostream> #include <cmath> int main() { double a, b, c; std::cin >> a >> b >> c; const double EPSILON = 1e-9; if ((a + b > c + EPSILON) && (a + c > b + EPSILON) && (b + c > a + EPSILON)) { std::cout << "Yes" << std::endl; } else { std::cout << "No" << std::endl; } return 0; }
11、相关网络资源推荐
- cppreference.com - Floating-point types - 浮点类型的权威参考。
- What Every Computer Scientist Should Know About Floating-Point Arithmetic - 深入理解浮点数误差的经典文章。
- OI Wiki - 浮点数 - 竞赛角度的浮点数讲解。