📄 一句话概括
实型常量(浮点数)就是带小数点的数,两种写法:小数形式 3.14、12.0,指数形式 1.5e3(=1500,e 表示乘 10 的几次方)。默认类型是 double,想用单精度的 float 要加后缀 f(3.14f)。必须记住的一条:浮点数存的是近似值,0.1 + 0.2 并不精确等于 0.3——涉及金额/精确比较时不能用浮点数直接判断相等。
一、两种写法
写法一:小数形式
3.14 0.5 -2.75 12.0 .5 // 都是合法的
- 必须有小数点:
12是整数(int),12.0才是实型(double) .5这种写法合法(等价于0.5),但不建议——容易看漏,写上0.5更清楚
写法二:指数形式(科学记数法)
1.5e3 // = 1.5 × 10³ = 1500
2.5E-2 // = 2.5 × 10⁻² = 0.025,e 可以写成大写 E
6.02e23 // 阿伏伽德罗常数,写大数很方便
读法:e 后面那个数,是"把小数点往哪边挪几位"。1.5e3 就是小数点右移 3 位 → 1500。
什么时候用指数形式:数值特别大或特别小的时候(光速 3.0e8、电子质量 9.1e-31),比数一串零清楚得多。
二、默认是 double,后缀能改
| 写法 | 类型 | 占内存 | 有效数字 | 说明 |
|---|---|---|---|---|
3.14 |
double(默认) |
8 字节 | 约 15~16 位 | 日常就用它 |
3.14f |
float |
4 字节 | 约 7 位 | 省内存;游戏/嵌入式常用 |
3.14L |
long double |
10/12/16 字节 | 比 double 更高 | 很少用 |
为什么默认是 double 而不是 float:float 只有约 7 位有效数字——一个十位数(比如手机号、大额金额)存进去,后面的数字就丢了。double 安全得多,而且现在内存便宜,所以默认用 double 是对的。
三、核心知识点:为什么浮点数"不准"
这不是 C++ 的 bug,是二进制表示法的必然:
十进制里,1/3 = 0.3333333... 永远写不完
二进制里,0.1 = 0.000110011001100... 也永远写不完
计算机只存有限的位数,存不下就只能截断——于是 0.1 存的其实是一个非常接近 0.1 的数。
后果:0.1 + 0.2 算出来是 0.30000000000000004,不等于 0.3。
所以三条实战规矩:
| 场景 | 正确做法 |
|---|---|
| 判断两个浮点数"相等" | 别用 ==;改判 fabs(a - b) < 1e-6(差值小到可以忽略就算相等) |
| 算金额 | 别用浮点。把"元"换算成"分"用整数算,或专用高精度方案 |
| 需要 7 位以上精度 | 用 double(float 不够) |
四、动手 Demo:亲眼看到 0.1 + 0.2 的真面目
新建 float.cpp(setprecision 是 2.5.3 的内容,这里先用):
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << setprecision(20); // 让我看到足够多的小数位
cout << "0.1 + 0.2 = " << 0.1 + 0.2 << endl;
cout << "0.3 = " << 0.3 << endl;
cout << "相等吗?" << (0.1 + 0.2 == 0.3 ? "相等" : "不相等") << endl;
return 0;
}
看到什么算成功:
0.1 + 0.2 = 0.30000000000000004441
0.3 = 0.29999999999999998890
相等吗?不相等
这一眼就是本节的全部价值——以后遇到"金额算错一分钱""判断条件莫名其妙不成立",先想想是不是浮点数在捣鬼。
30 秒实验:把 float 和 double 放一起比精度:
float f = 1.0f / 3.0f;
double d = 1.0 / 3.0;
cout << setprecision(15);
cout << "float = " << f << endl; // 0.333333343267441(后几位是错的)
cout << "double = " << d << endl; // 0.333333333333333(准得多)
五、常见误区
- "
12.和12一样"——不一样。12.是实型(小数部分为 0),12是整型。这决定了5 / 2是 2 还是 2.5 - "
float和double只差内存"——还差精度。float约 7 位有效数字,double约 15~16 位;写金融、科学计算时用错会直接算错 - "浮点数算得不准,是编译器有问题"——不是。任何用二进制浮点的语言都一样(Java、Python、JavaScript 都是这个行为)
- "用
==比较浮点也行,我试过大部分时候对"——"大部分时候对"正是最可怕的。它一定会在某次生产环境的金额校验上翻车
自测四问(点开对答案)
1. 实型常量的两种写法分别是什么?——**小数形式**(`3.14`)和**指数形式**(`1.5e3`=1500)。 2. 不加后缀的 `3.14` 是什么类型?——`double`(默认);想用 `float` 要写 `3.14f`。 3. 为什么 `0.1 + 0.2 != 0.3`?——二进制无法精确表示 `0.1`,存的是近似值,相加后误差露出来。 4. 判断两个浮点数相等该怎么做?——不用 `==`,改用"差的绝对值小于一个极小值"(如 `fabs(a-b) < 1e-6`)。- ☑ 字符常量