🔷 第二章 C++语言基础
📄 一句话概括

实型常量(浮点数)就是带小数点的数,两种写法:小数形式 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      // 都是合法的

写法二:指数形式(科学记数法)

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(准得多)

五、常见误区

  1. "12. 和 12 一样"——不一样。12. 是实型(小数部分为 0),12 是整型。这决定了 5 / 2 是 2 还是 2.5
  2. "float 和 double 只差内存"——还差精度。float 约 7 位有效数字,double 约 15~16 位;写金融、科学计算时用错会直接算错
  3. "浮点数算得不准,是编译器有问题"——不是。任何用二进制浮点的语言都一样(Java、Python、JavaScript 都是这个行为)
  4. "用 == 比较浮点也行,我试过大部分时候对"——"大部分时候对"正是最可怕的。它一定会在某次生产环境的金额校验上翻车
自测四问(点开对答案) 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`)。

相关笔记