原始题目

以下代码的输出是什么?

double x = 123456.789;
cout << scientific << x;

答案:1.234568e+05


逐步拆解

  1. scientific 是浮点格式操纵符,等价于 printf%e,把数字写成 d.ddde±dd 形式。
  2. 默认精度是 6。这一点最容易忽略:不写 setprecision 时,cout 的默认 precision 就是 6。
  3. scientific(以及默认 defaultfloat)下,precision(6) 表示 6 位有效数字
  4. 所以 123456.7891.23456789 × 10⁵,保留 6 位有效数字并四舍五入
1.23456|789   →  第7位 7 进位
= 1.234568e+05

注意末位是 …568,不是 …567,很多同学直接截断就写错了。

  1. 指数部分固定至少 2 位、带符号e+05(不是 e5,也不是 e+5)。

同一个 x 的几种写法对比

写法 输出 说明
cout << x 123457 默认 defaultfloat,6 位有效数字
cout << scientific << x 1.234568e+05 科学计数法,6 位有效数字
cout << fixed << x 123456.789000 fixed 下精度 6 = 小数点后 6 位
cout << setprecision(3) << scientific << x 1.235e+05 改成 3 位有效数字
cout << setprecision(3) << fixed << x 123456.789 改成小数点后 3 位
cout << defaultfloat << x 123457 取消 fixed/scientific,回到默认

最大坑点setprecision(n) 的含义随格式标志变化——

  • fixed小数点后 n 位
  • scientific / defaultfloatn 位有效数字

精度是“粘”在流上的

scientificsetprecision 一旦设置就一直生效,后面的输出全部受影响:

cout << scientific << 123.456 << " " << 0.5;
// 1.234560e+02 5.000000e-01

cout << fixed << setprecision(2);
cout << 3.14159;   // 3.14
cout << 2.0;       // 2.00  ← 也受影响

想恢复默认:cout << defaultfloat << setprecision(6);

常见配套操纵符

#include <iomanip>
cout << setprecision(2) << fixed;   // 保留 2 位小数(OI 最常用)
cout << setw(6) << left;            // 宽度 6,左对齐

注意 setw 只对紧接着的下一个输出有效,setprecisionfixed/scientific 则长期有效。

冷知识:fixed + scientific 同时设置

cout << fixed << scientific << x;

标准规定:两个标志同时置位时,按 hexfloat(%a) 处理,输出形如 0x1.e240c9fbe76c9p+16(十六进制浮点)。这也正是 std::hexfloat 的实现方式。

考点总结(CSP-J 初赛选择题)

  1. 记住默认精度 6
  2. scientific/默认 → 有效数字;fixed → 小数位数。
  3. 结果要四舍五入,不是截断。
  4. 指数格式至少 2 位并带符号:e+05

思考题

cout << fixed << setprecision(2) << 3.145 << " " << 3.135; 输出是什么?

答案 3.14 3.14(注意不是 3.15:3.135 在 double 中的二进制值略小于 3.135,四舍五入后为 3.14;这正是浮点数不能用 == 比较的原因)。